为什么纹理数据无法显示?
Why texture data can't show?
我尝试用GLKit
来显示立方体。但是有些麻烦使我感到困惑。我无法加载我的纹理。代码如下:
import UIKit
import OpenGLES
import GLKit
struct CubeVertex {
var positionCoord: GLKVector3
var textureCoord: GLKVector2
}
class ViewController: UIViewController {
lazy var glkView: GLKView = {
let glkView = GLKView(frame: CGRect(x: 0, y: 200, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width))
glkView.backgroundColor = .purple
//使用深度缓存
glkView.drawableDepthFormat = GLKViewDrawableDepthFormat.format24
glkView.delegate = self
view.addSubview(glkView)
return glkView
}()
lazy var baseEffect: GLKBaseEffect = {
let baseEffect = GLKBaseEffect()
return baseEffect
}()
//顶点数
let kCoordCount = 36
lazy var vertices: UnsafeMutablePointer<CubeVertex> = {
let verticesSize = MemoryLayout<CubeVertex>.size * kCoordCount
let vertices = UnsafeMutablePointer<CubeVertex>.allocate(capacity: verticesSize)
return vertices
}()
lazy var displayLink: CADisplayLink = {
let displayLink = CADisplayLink(target: self, selector: #selector(glkViewDisplay))
return displayLink
}()
var angle = 0
var vertexBuffer = GLuint()
override func viewDidLoad() {
super.viewDidLoad()
setupContext()
setupEffect()
setupVertexData()
addDisplayLink()
}
private func setupContext() {
if let context = EAGLContext(api: EAGLRenderingAPI.openGLES3) {
EAGLContext.setCurrent(context)
glkView.context = context
}
}
private func setupEffect() {
guard let imagePath = Bundle.main.path(forResource: "me", ofType: "png", inDirectory: nil),
let image = UIImage(contentsOfFile: imagePath)?.cgImage
else { return }
let options = [GLKTextureLoaderOriginBottomLeft : NSNumber(value: true)]
let textureInfo = try? GLKTextureLoader.texture(with: image, options: options)
if let textureInfo = textureInfo, let target = GLKTextureTarget(rawValue: textureInfo.target) {
baseEffect.texture2d0.name = textureInfo.name
baseEffect.texture2d0.target = target
}
}
private func setupVertexData() {
// front
self.vertices[0] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[1] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 0)))
self.vertices[2] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[3] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 0)))
self.vertices[4] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[5] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (1, 0)))
// above
self.vertices[6] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[7] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[8] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[9] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[10] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[11] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
// below
self.vertices[12] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[13] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[14] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[15] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[16] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[17] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
// left
self.vertices[18] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[19] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[20] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[21] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[22] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[23] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
// right
self.vertices[24] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[25] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[26] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[27] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[28] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[29] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
// back
self.vertices[30] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[31] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
self.vertices[32] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[33] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
self.vertices[34] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[35] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
glGenBuffers(1, &vertexBuffer)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)
let bufferSize = MemoryLayout<CubeVertex>.size * kCoordCount
glBufferData(GLenum(GL_ARRAY_BUFFER), bufferSize, self.vertices, GLenum(GL_STATIC_DRAW))
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.position.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.position.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(0))
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.texCoord0.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(MemoryLayout<GLKVector3>.size))
}
private func BUFFER_OFFSET(_ i: Int) -> UnsafeRawPointer? {
return UnsafeRawPointer(bitPattern: i)
}
private func addDisplayLink() {
displayLink.add(to: RunLoop.main, forMode: .common)
}
@objc private func glkViewDisplay() {
angle = (angle + 3) % 360
let radians = GLKMathDegreesToRadians(Float(angle))
baseEffect.transform.modelviewMatrix = GLKMatrix4MakeRotation(radians, 0.5, 0.3, 0.4)
glkView.display()
}
}
extension ViewController: GLKViewDelegate {
func glkView(_ view: GLKView, drawIn rect: CGRect) {
glEnable(GLenum(GL_DEPTH_TEST))
glClear(GLbitfield(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT))
baseEffect.prepareToDraw()
glDrawArrays(GLenum(GL_TRIANGLES), 0, GLsizei(kCoordCount))
}
}
问题可能出现在下面的代码中:
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.texCoord0.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(MemoryLayout<GLKVector3>.size))
但是我不知道怎么解决
我找到了解决这个问题的方法。但是原因也让我很困惑。使用以下代码:
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(MemoryLayout<GLKVector3>.size + 4))
替换代码:
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(MemoryLayout<GLKVector3>.size))
可以解决问题。这意味着偏移量是 16
而不是 12
。它还有两个问题让我很困惑:
CubeVertex
尺寸是 24
而不是 20
。
- 偏移量是
16
而不是 12
我尝试用GLKit
来显示立方体。但是有些麻烦使我感到困惑。我无法加载我的纹理。代码如下:
import UIKit
import OpenGLES
import GLKit
struct CubeVertex {
var positionCoord: GLKVector3
var textureCoord: GLKVector2
}
class ViewController: UIViewController {
lazy var glkView: GLKView = {
let glkView = GLKView(frame: CGRect(x: 0, y: 200, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width))
glkView.backgroundColor = .purple
//使用深度缓存
glkView.drawableDepthFormat = GLKViewDrawableDepthFormat.format24
glkView.delegate = self
view.addSubview(glkView)
return glkView
}()
lazy var baseEffect: GLKBaseEffect = {
let baseEffect = GLKBaseEffect()
return baseEffect
}()
//顶点数
let kCoordCount = 36
lazy var vertices: UnsafeMutablePointer<CubeVertex> = {
let verticesSize = MemoryLayout<CubeVertex>.size * kCoordCount
let vertices = UnsafeMutablePointer<CubeVertex>.allocate(capacity: verticesSize)
return vertices
}()
lazy var displayLink: CADisplayLink = {
let displayLink = CADisplayLink(target: self, selector: #selector(glkViewDisplay))
return displayLink
}()
var angle = 0
var vertexBuffer = GLuint()
override func viewDidLoad() {
super.viewDidLoad()
setupContext()
setupEffect()
setupVertexData()
addDisplayLink()
}
private func setupContext() {
if let context = EAGLContext(api: EAGLRenderingAPI.openGLES3) {
EAGLContext.setCurrent(context)
glkView.context = context
}
}
private func setupEffect() {
guard let imagePath = Bundle.main.path(forResource: "me", ofType: "png", inDirectory: nil),
let image = UIImage(contentsOfFile: imagePath)?.cgImage
else { return }
let options = [GLKTextureLoaderOriginBottomLeft : NSNumber(value: true)]
let textureInfo = try? GLKTextureLoader.texture(with: image, options: options)
if let textureInfo = textureInfo, let target = GLKTextureTarget(rawValue: textureInfo.target) {
baseEffect.texture2d0.name = textureInfo.name
baseEffect.texture2d0.target = target
}
}
private func setupVertexData() {
// front
self.vertices[0] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[1] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 0)))
self.vertices[2] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[3] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 0)))
self.vertices[4] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[5] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (1, 0)))
// above
self.vertices[6] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[7] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[8] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[9] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[10] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[11] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
// below
self.vertices[12] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[13] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[14] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[15] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[16] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[17] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
// left
self.vertices[18] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[19] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[20] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[21] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[22] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[23] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
// right
self.vertices[24] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, 0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[25] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[26] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[27] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, 0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[28] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
self.vertices[29] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
// back
self.vertices[30] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (0, 1)))
self.vertices[31] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
self.vertices[32] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[33] = CubeVertex(positionCoord: GLKVector3(v: (-0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (0, 0)))
self.vertices[34] = CubeVertex(positionCoord: GLKVector3(v: (0.5, 0.5, -0.5)), textureCoord: GLKVector2(v: (1, 1)))
self.vertices[35] = CubeVertex(positionCoord: GLKVector3(v: (0.5, -0.5, -0.5)), textureCoord: GLKVector2(v: (1, 0)))
glGenBuffers(1, &vertexBuffer)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)
let bufferSize = MemoryLayout<CubeVertex>.size * kCoordCount
glBufferData(GLenum(GL_ARRAY_BUFFER), bufferSize, self.vertices, GLenum(GL_STATIC_DRAW))
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.position.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.position.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(0))
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.texCoord0.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(MemoryLayout<GLKVector3>.size))
}
private func BUFFER_OFFSET(_ i: Int) -> UnsafeRawPointer? {
return UnsafeRawPointer(bitPattern: i)
}
private func addDisplayLink() {
displayLink.add(to: RunLoop.main, forMode: .common)
}
@objc private func glkViewDisplay() {
angle = (angle + 3) % 360
let radians = GLKMathDegreesToRadians(Float(angle))
baseEffect.transform.modelviewMatrix = GLKMatrix4MakeRotation(radians, 0.5, 0.3, 0.4)
glkView.display()
}
}
extension ViewController: GLKViewDelegate {
func glkView(_ view: GLKView, drawIn rect: CGRect) {
glEnable(GLenum(GL_DEPTH_TEST))
glClear(GLbitfield(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT))
baseEffect.prepareToDraw()
glDrawArrays(GLenum(GL_TRIANGLES), 0, GLsizei(kCoordCount))
}
}
问题可能出现在下面的代码中:
glEnableVertexAttribArray(GLuint(GLKVertexAttrib.texCoord0.rawValue))
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(MemoryLayout<GLKVector3>.size))
但是我不知道怎么解决
我找到了解决这个问题的方法。但是原因也让我很困惑。使用以下代码:
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(MemoryLayout<GLKVector3>.size + 4))
替换代码:
glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue), 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(MemoryLayout<CubeVertex>.size), BUFFER_OFFSET(MemoryLayout<GLKVector3>.size))
可以解决问题。这意味着偏移量是 16
而不是 12
。它还有两个问题让我很困惑:
CubeVertex
尺寸是24
而不是20
。- 偏移量是
16
而不是12