How do I keep the title bar from causing rendering issues in Metal? - swift

When I draw any shape (Whether it's textured or not) it will flicker when I go to fullscreen and make the title bar show when I move the mouse to the top. It will turn lighter and then back for like a split second. I don't know if this happens with solid colors, but when I color the vertices and draw a gradient or apply textures, this happens. It's annoying, even though it's subtle. How can I fix it?
How to reproduce: Create a shape in Metal, either color the vertices differently to create a gradient, or apply a texture to it, and make the window fullscreen. Move the cursor to the top of the window. When the title bar shows up, the shape/texture will flash briefly. How can I fix that?
I am using macOS 1.15 Catalina.
This can be demonstrated even with the Xcode's example Metal game. Just go to fullscreen, show the title bar, and it will be unsmooth when you show and unshow the titlebar.
UPDATE: I have realized, that if I put the drawing code in viewDidLoad() instead of draw() this behavior will cease. How do I make it so that it's not buggy without having to only render ONE frame?
ANOTHER UPDATE: It does occur for solid colors.
This is a very difficult question, because I don't know what to try. This bug is also very hard to fix, because it only sometimes happens.
Example of the bug (Video)
Another example of the bug that displays the "white flicker" (Video)
Also this question was only half answered, because it turns out that I managed to fix the problem of the titlebar blocking the framerate, but there is still a problem with the white flash.

After watching your video, I understand what your problem is. In your case UI (Tittle Bar) is blocking the main thread, it's normal behavior because MTKView rendering occurs on the main application threads. You need to create a custom metal view and implement a render loop on a background thread.

Your best bet is to report this as a bug to Apple. I tried to research and there seems to be no results about this bug.
I assume you want a fix, but all I got is a workaround:
It doesn't seem to occur while the drawing code only runs once, in viewDidLoad. Maybe you could keep it there, and manually call the MetalView's draw method 60 times a second. I figured out how to get what I said to work. Leave the drawing code in draw, but make sure to set the preferred framerate to 0. Then manually redraw it 60 times a second. Because the draw method auto redrawing is buggy in this sense.

Related

endless vertical scrolling background

I want to make an endless vertical scrolling layer that gives the impression that the main character is moving upwards. I have been brainstorming on how to achieve this.
My issue is that I want objects to appear as if they are coming from above and below the screen at the same time. Secondly, I want to be able to move the main character to create and destroy box2d joints between it and some of the objects appearing on the screen. What is the best way to achieve this with consuming too much memory? I would appreciate any help on this.
Apple did a wonderful tutorial of this in a WWDC 2011 video session. It was "UITableView Changes, Tips & Tricks" and it's about 35m40sec into the video.
Since the use of the UITableView is really just a UIScrollView for the purposes of the background, you could just use a UIScrollView and you can either have it move on timer or events as needed.
Think of your player as moving within a stationary bounding box. The background can scroll using the aforementioned pooling method (as the background tile scrolls off the screen it is placed into a pool, and before a new tile is instantiated the pool is checked for available reusable tiles). Thirdly, your enemy objects will simply approach from either the bottom of the screen or the top.
Imagine your idea without the scrolling background (flying effect) and you should find that the problem is relatively straightforward.
I also needed and endless scrolling background layer. This can do exactly that, and it is super simple to set up and use. Just copy the four files in to the cocos2d folder in your project, then follow the quick tutorial seen on the github. Make sure the image you use is seamless (when you line them up vertically you can't tell where one ends.

UIScrollView sporadically loses bounce and fluid scrolling

I have successfully implemented a working UIScrollView layer on top of Cocos2d using this fantastic tutorial:
http://bitbattalion.com/2011/09/uikit-uiscrollview-and-cocos2d/
However, the scroll view sporadically becomes sluggish and choppy, including almost always upon loading the scene. When it happens, the scrolling and is no longer is able to be flicked up or down with any sort of variable velocity. It also loses all of it's bounce and just stay partially of screen until the next touch is registered.
The weird thing is though, that if I simply pull down my Notification Center, it fixes the scroll view every time. The scrolling all of a sudden becomes perfectly fluid and the edges bounce beautifully into place.
What is happening here?
Instruments may help to tackle the problem. Run using the CoreAnimation Tool so you can get a good handle on where you might be experiencing the drop in frame rate. You'll need to have your device connected to run the CoreAnimation tool.
This tutorial is also available at http://mobileoverlord.com/instruments-optimizing-core-animation/
Select Profile from the build scheme.
Select the CoreAnimation Profiling Tool
When the tool is running scroll around in your scroll view and keep an eye on frame rate. 60 is great.
If you need to dial in on it any more you can turn on Color Blended Layers from the Debug Options in the Instruments Panel View(Menu) -> Instruments
Without Color Blended Layers (Left)
With Color Blended Layers (Right)
The basic rule of thumb here is, the more red you see the less optimized the view is for the animation. Although, you don't want to remove all red either, %50 is about right.

iPhone: Fade In on Application Load

I have my app up and running and would like to add some polish to it. One of the first things I'd like to do is improve the transitions.
Unfortunately I have speent most of my time in OpenGL and still haven't got a solid grasp on working with the UIView system. What is a good way to enter into your App?
I load pretty quickly so I was thinking a quick fade in, but my GL view loads and draws at least a frame before I really get control so I am not sure the best way to go about this.
A quick and dirty way would be to just create a black (or white) solid color full screen UIView overlaying the opengl view, and have it fade its alpha down to zero over some n number of seconds.
There is a SetAlpha method from UIView. In your draw call; decrease gradually the alpha value until 0. When it hits 0, then draw the next "view" of your app (pretty much loads your next 3d objects); and increase the alpha back to 1. should do the trick.

White edge when orienting dark colored view?

I am just playing with an iPhone test app that orients the view when the simulator is rotated left or right. Everything worked fine when my view had a white background, however when I altered the view background to a darker color I noticed a white edge (1 pixel) around the view as it rotates. Has anyone come across this before or know how I might get rid of it. Indeed it might be an issue with the simulator that won't show on the actual device, but I just thought it worth asking for future reference.
gary
I have seen something similar before..
Go through the nib (.xib) files and make sure that all of the views have an appropriate dark background colour set, most notably the nib file which contains the "window". Click on them and set the background colour.
I've never noticed it but then again I've never tried to rotate a very dark view. There might be a small border to keep the view from visually bleeding into the status bars or other views.
Rotation and scaling in the discrete domain( as against analog) is quite difficult, because after a rotation/scaling the rotated location may not be a pixel location. You can suppress the effect by smoothening the edges, but I believe that is not implemented, and so the bug.

Tinting iPhone application screen red

I'm trying to place a red tint on all the screens of my iPhone application. I've experimented on a bitmap and found I get the effect I want by compositing a dark red color onto the screen image using Multiply (kCGBlendModeMultiply).
So the question is how to efficiently do this in real time on the iPhone?
One dumb way might be to grab a bitmap of the current screen, composite into the bitmap and then write the composited bitmap back to the screen. This seems like it would almost certainly be too slow. In addition, I need some way of knowing when part of the screen has been redrawn so I can update the tinting.
I can almost get the effect I want by putting a red, translucent, fullscreen UIView above everything. That tints everything red within further intervention on my part, but the effect is much "muddier" than results from the composite.
So do any wizards out there know of some mechanism I can use to automatically composite the red over the app in similar fashion to what the translucent red UIView does?
I managed to somewhat make this work but with some side-effects:
I setup a UIView on top of all my app-views (attached to the window) which is not userInteractionEnabled and which is opaque
This UIView carries some custom drawRect-method which first fills the complete area with red color and then after having made a "screenshot" of my window-viewhierarchy I am rendering this image with
CGContextSetBlendMode( c, kCGBlendModeMultiply);
to the UIView.
To constantly update this UIView to the current state of the apps UIViews I constantly produce "screenshots" and render them as fast as possible.
I setup an NSTimer which is doing this snapshotting/rendering in a defined frequency and which is added to the the NSRunLoop for "Tracking".
RESULT: some really laggy response from the UI with several fancy effects, but still usable though if you do not set the frequency of snapshotting/rendering to high.
See screenshot here...
The result looks okay, but the usability really suffers a lot. I had a look at the OpenGL-examples before trying this aproach, but OpenGL is a whole lot of different (mostly C) code which seems to be very near to the hardware and which gives you a real headache.
So, the described approach is what I will shoot for with my next app. I hope Apple accepts it even though it degrades UXP during nightvision mode. They should simply make CALayer filter-backed then my problem will definitely be solved a whole lot better and performing nicely.
You could try this: subclass UIView. Add code to -drawRect method to draw the overlay. Make your UIView subclass pose as UIView everywhere in your app with
class_poseAs ([CustomUIView class], [UIView class]);