@mjeragh - I’m glad that it has helped you . Thank you for pointing this out, and I’ve passed it on. If you’re having trouble in the meantime, the epub version has quality images.
I’ve just downloaded the book and supporting files. It looks like the Xcode projects in 24-synchronization-and-multithreading are the same as in 23-debugging-and-profiling?
I like the asset catalog and hopefully it will work again in the future. In the meantime, instead of adding the image to the asset catalog, you can add the png image directly to the project. The code should automatically load from the project rather than the catalog.
Hi - Did you try rebooting your computer? Sometimes playgrounds can get confused.
Also, could you provide more details about the Xcode version and your hardware, please? My playground works on a MacBook Pro 2019 (GPU Vega 20) and Xcode 11.4.1
In the Camera.swift file we have the ArcballCamera class and we override the rotation variable. When the user wants to pan or rotate the view this variable is updated in the overridden rotate function at the bottom of the class. The problem is that when you try to rotate the view it throws the following error:
EXC_BAD_ACCESS(EXC_I386_GPFLT)
From what I can tell this is thrown when there is memory protection. So I assume we are accessing the rotation variable incorrectly (as the error suggests). But here comes the interesting part… I decided to check if I can print out to the console want is stored in the rotation variable. When I do that I can access the variable and see what the current value is.
My solution was to add print statements before each update of the rotation variable inside the rotate function like so:
For some reason this actually works and I can’t figure out why. FYI if I remove any of those print statements, the very next access of rotation throws the same error as before. Also this only works if I specifically say “print(rotation.y)” or “print(rotation.x)”, and it throws the error if is simply say “print(rotation)”. It just seems so strange that this what fixes it. What is a better way of fixing this issue?
The solution is to assign the whole [x, y, z] float3 value to the rotation at one time.
override func rotate(delta: float2) {
let sensitivity: Float = 0.005
var x = rotation.x + delta.y * sensitivity
x = max(-Float.pi/2, min((x), Float.pi/2))
let y = rotation.y + delta.x * sensitivity
// Need to assign the whole [x, y, z] float3 value to the rotation at one time
rotation = [x, y, 0]
_viewMatrix = updateViewMatrix()
}
It actually should read “If you want to”, but perhaps the rest of the sentence could be better. How about:
“If you want to draw the same vertex array but in two different positions, then you’ll need two different buffers.”
Let me explain.
You want to draw the vertices twice. First in one position and then in another. Your code says
set vertex positions in vertex array
draw
override the new vertex positions in the same vertex array
draw
In a serial world, that would work. However, when drawing on the GPU, all draws are batched together. So steps 2 and 4 might be done simultaneously. This means that you need to maintain two different data sources to be able to do the drawing.
I have been working through the 3D Graphics with Metal video course and this issue (EXC_BAD_ACCESS(EXC_I386_GPFLT)) appears in all of the projects after the ArcballCamera class was introduced.