为什么在用于 OpenGL 纹理的 CGContext 上调用绘制函数时会出现 BAD_ACCESS 错误?
Why am I getting a BAD_ACCESS fault when calling draw functions on a CGContext used for an OpenGL texture?
我正在尝试使用 Core Graphics 创建 OpenGL 纹理。我的代码设置在 prepareOpenGL()
中。在绘制初始化的 CGContext
时,出现 EXC_BAD_ACCESS
错误。但是,当我在 LLDB 中 po 上下文时(po context!
,见下文),我得到一个包含所有 CGContext 信息的地址。我也试过通过 LLDB 调用表达式,输出是 nil
。地址清理器、线程清理器和僵尸程序是非暴露的。我的问题是,当 Optional<CGContext>
不是 nil
时,为什么 CGContext 被声明为 nil,EXC_BAD_ACCESS
?我曾尝试在 drawRect(_:)
中调用此代码,但我得到了相同的结果。
import Cocoa
import CoreGraphics
import OpenGL.GL3
class MyView: NSOpenGLView {
var textureTBO: GLuint = 0
override func prepareOpenGL() {
let bitmapRows = 10
let bitmapColumns = 10
let floatsPerPoint = 4
var bitmapBuffer = UnsafeMutablePointer<CGFloat>.allocate(capacity: bitmapRows * bitmapColumns * floatsPerPoint)
if let context = CGContext(data: &bitmapBuffer,
width: bitmapColumns,
height: bitmapRows,
bitsPerComponent: 8,
bytesPerRow: bitmapColumns * floatsPerPixel,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue) {
context.setFillColor(red: 0, green: 0, blue: 1, alpha: 0.5)
context.fill(CGRect(x: 0, y: 0, width: 5, height: 5)) //=> EXC_BAD_ACCESS, code=2
context.setFillColor(red: 1, green: 0, blue: 1, alpha: 0.5)
context.fill(CGRect(x: 5, y: 5, width: 5, height: 5))
context.setFillColor(red: 0, green: 1, blue: 0, alpha: 0.5)
context.fill(CGRect(x: 0, y: 5, width: 5, height: 5))
context.setFillColor(red: 0.5, green: 0, blue: 0.5, alpha: 0.5)
context.fill(CGRect(x: 5, y: 0, width: 5, height: 5))
glGenTextures(1, &textureTBO)
glBindTexture(GLenum(GL_TEXTURE_2D), textureTBO)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_REPEAT)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_REPEAT)
}
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GLint(GL_RGB), 256, 256, 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_INT), &bitmapBuffer)
bitmapBuffer.deallocate()
}
}
LLDB 输出 - 可选不为零
(lldb) po context!
<CGContext 0x7b3000000300> (kCGContextTypeBitmap)
<<CGColorSpace 0x7b1800002280> (kCGColorSpaceDeviceRGB)>
width = 256, height = 256, bpc = 8, bpp = 32, row bytes = 2048
kCGImageAlphaNoneSkipLast | 0 (default byte order)
LLDB 输出 - 这是否告诉我无法设置颜色,因为上下文实际上是 nil?
(lldb) expression context?.setFillColor(red: 0, green: 0, blue: 1, alpha: 0.5)
(Void?) $R4 = nil
LLDB 输出 - 徒劳的练习:做同样的事情并期待不同的结果,哈哈
(lldb) expression context?.fill(CGRect(x: 0, y: 0, width: 5, height: 5))
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=2, address=0x7b08000c7ff0).
The process has been returned to the state before expression evaluation.
我发现this answer好像可以做到这一点。我很欣赏你的想法,谢谢!
data: &bitmapBuffer
是指向缓冲区的指针。将其替换为 data: bitmapBuffer
.
与崩溃无关,但每个组件 8 位适合 UInt8
:
var bitmapBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bitmapRows * bitmapColumns * floatsPerPoint)
我正在尝试使用 Core Graphics 创建 OpenGL 纹理。我的代码设置在 prepareOpenGL()
中。在绘制初始化的 CGContext
时,出现 EXC_BAD_ACCESS
错误。但是,当我在 LLDB 中 po 上下文时(po context!
,见下文),我得到一个包含所有 CGContext 信息的地址。我也试过通过 LLDB 调用表达式,输出是 nil
。地址清理器、线程清理器和僵尸程序是非暴露的。我的问题是,当 Optional<CGContext>
不是 nil
时,为什么 CGContext 被声明为 nil,EXC_BAD_ACCESS
?我曾尝试在 drawRect(_:)
中调用此代码,但我得到了相同的结果。
import Cocoa
import CoreGraphics
import OpenGL.GL3
class MyView: NSOpenGLView {
var textureTBO: GLuint = 0
override func prepareOpenGL() {
let bitmapRows = 10
let bitmapColumns = 10
let floatsPerPoint = 4
var bitmapBuffer = UnsafeMutablePointer<CGFloat>.allocate(capacity: bitmapRows * bitmapColumns * floatsPerPoint)
if let context = CGContext(data: &bitmapBuffer,
width: bitmapColumns,
height: bitmapRows,
bitsPerComponent: 8,
bytesPerRow: bitmapColumns * floatsPerPixel,
space: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGImageAlphaInfo.noneSkipLast.rawValue) {
context.setFillColor(red: 0, green: 0, blue: 1, alpha: 0.5)
context.fill(CGRect(x: 0, y: 0, width: 5, height: 5)) //=> EXC_BAD_ACCESS, code=2
context.setFillColor(red: 1, green: 0, blue: 1, alpha: 0.5)
context.fill(CGRect(x: 5, y: 5, width: 5, height: 5))
context.setFillColor(red: 0, green: 1, blue: 0, alpha: 0.5)
context.fill(CGRect(x: 0, y: 5, width: 5, height: 5))
context.setFillColor(red: 0.5, green: 0, blue: 0.5, alpha: 0.5)
context.fill(CGRect(x: 5, y: 0, width: 5, height: 5))
glGenTextures(1, &textureTBO)
glBindTexture(GLenum(GL_TEXTURE_2D), textureTBO)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_REPEAT)
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_REPEAT)
}
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GLint(GL_RGB), 256, 256, 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_INT), &bitmapBuffer)
bitmapBuffer.deallocate()
}
}
LLDB 输出 - 可选不为零
(lldb) po context!
<CGContext 0x7b3000000300> (kCGContextTypeBitmap)
<<CGColorSpace 0x7b1800002280> (kCGColorSpaceDeviceRGB)>
width = 256, height = 256, bpc = 8, bpp = 32, row bytes = 2048
kCGImageAlphaNoneSkipLast | 0 (default byte order)
LLDB 输出 - 这是否告诉我无法设置颜色,因为上下文实际上是 nil?
(lldb) expression context?.setFillColor(red: 0, green: 0, blue: 1, alpha: 0.5)
(Void?) $R4 = nil
LLDB 输出 - 徒劳的练习:做同样的事情并期待不同的结果,哈哈
(lldb) expression context?.fill(CGRect(x: 0, y: 0, width: 5, height: 5))
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=2, address=0x7b08000c7ff0).
The process has been returned to the state before expression evaluation.
我发现this answer好像可以做到这一点。我很欣赏你的想法,谢谢!
data: &bitmapBuffer
是指向缓冲区的指针。将其替换为 data: bitmapBuffer
.
与崩溃无关,但每个组件 8 位适合 UInt8
:
var bitmapBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bitmapRows * bitmapColumns * floatsPerPoint)