首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >动态改变金属顶点颜色的正确方法是什么?

动态改变金属顶点颜色的正确方法是什么?
EN

Stack Overflow用户
提问于 2015-04-10 05:17:44
回答 1查看 1.6K关注 0票数 1

我正试着进入金属业。我已经做了一些OpenGL,但是已经很多年了,所以我想不出正确的方法来做到这一点。我一直在使用关于Ray Wenderlich (http://www.raywenderlich.com/81399/ios-8-metal-tutorial-swift-moving-to-3d)的金属教程的介绍

我有一个顶点结构:

代码语言:javascript
复制
struct Vertex
{
    var x, y, z: Float
    var r, g, b, a: Float

    func floatBuffer() -> Array<Float>
    {
        return [x, y, z, r, g, b, a]
    }
}

和一个顶点缓冲区类:

代码语言:javascript
复制
class VertexBuffer
{
    var vertexData = Array<Float>()

    init(vertices: Array<Vertex>)
    {
        var vertexData = Array<Float>()

        for vertex in vertices
        {
            vertexData += vertex.floatBuffer()
        }

        self.vertexData = vertexData
    }

    func updateColorOfVertexAtIndex(index: Int, newRed: CGFloat, newGreen: CGFloat, newBlue: CGFloat, newAlpha: CGFloat)
    {
        let vertexDataIndex = index * 7

        if (vertexDataIndex < self.vertexData.count)
        {
            self.vertexData[vertexDataIndex + 3] = Float(newRed)
            self.vertexData[vertexDataIndex + 4] = Float(newGreen)
            self.vertexData[vertexDataIndex + 5] = Float(newBlue)
            self.vertexData[vertexDataIndex + 6] = Float(newAlpha)
        }
    }

    func updateColorOfVertexAtIndex(index: Int, newColor: UIColor)
    {
        var red: CGFloat = 0.0
        var green: CGFloat = 0.0
        var blue: CGFloat = 0.0
        var alpha: CGFloat = 0.0

        newColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)

        self.updateColorOfVertexAtIndex(index, newRed: red, newGreen: green, newBlue: blue, newAlpha: alpha)
    }
}

基于其他应用程序的状态,我想更新一个或多个顶点的RGBA。使用VertexBuffer.updateColor...方法,我将在VertexBuffer.vertexData中更新相应的RGBA值。我有一个连接到以下函数的CADisplayLink:

代码语言:javascript
复制
func diffusionLoop()
{
    self.updateVertexData()

    var vertexData = self.inkVertexBuffer.vertexData

    let dataSize = vertexData.count * sizeofValue(vertexData[0])
    let vertexBuffer = self.device.newBufferWithBytes(vertexData, length: dataSize, options: nil)


    autoreleasepool { () -> () in
        self.renderColorsWithVertexBuffer(vertexBuffer)
    }
}

func renderColorsWithVertexBuffer(vertexBuffer: MTLBuffer)
    {
        let renderPassDescriptor = MTLRenderPassDescriptor()
        let drawable = self.metalLayer.nextDrawable()

        renderPassDescriptor.colorAttachments[0].texture = drawable.texture
        renderPassDescriptor.colorAttachments[0].loadAction = .Clear
        renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0, 1.0, 1.0, 0.0)
        renderPassDescriptor.colorAttachments[0].storeAction = .Store

        let commandBuffer = self.commandQueue.commandBuffer()

        if let renderEncoder = commandBuffer.renderCommandEncoderWithDescriptor(renderPassDescriptor) {
            renderEncoder.setRenderPipelineState(self.pipelineState)
            renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, atIndex: 0)
            renderEncoder.drawPrimitives(.Triangle, vertexStart: 0, vertexCount: self.vertexCount, instanceCount: self.triangleCount)
            renderEncoder.endEncoding()
        }

        commandBuffer.presentDrawable(drawable)
        commandBuffer.commit()
    }

问题是,我不知道这样做是否正确。我的目标是经常更新某些顶点的颜色,但是每次都要修改顶点数据并创建一个MTLBuffer吗?还是别的什么?

任何帮助都将不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-10 07:20:16

理想情况下,您不希望更新vertexBuffer's值。在我看来,最好的方法是将不变的数据与可变的数据分开。

因此,我将创建单独的带有颜色值的统一缓冲区,并更新它,而不是vertexBuffer本身。

您还说过“基于其他应用程序的状态--我想更新一个或多个顶点.的RGBA”,最好将这些“状态”作为常量传递给着色器和着色器内部,以计算每个顶点或片段的颜色。

顶点着色器有:

代码语言:javascript
复制
unsigned int vid [[ vertex_id ]]

可以显式设置每个顶点的颜色。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29553923

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档