为什么纹理数据无法显示?

时间:2019-06-08 05:08:05

标签: ios swift opengl-es glkit

我尝试使用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))

但是我不知道如何解决。

1 个答案:

答案 0 :(得分:0)

我找到了解决此问题的方法。但是原因也使我感到困惑。使用以下代码:

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。它还有两个问题使我感到困惑:

  1. CubeVertex的大小是24,而不是20
  2. 偏移量是16而不是12