gpt4 book ai didi

ios - iOS。 OpenGL。同时几个 View

转载 作者:行者123 更新时间:2023-12-03 01:51:12 26 4
gpt4 key购买 nike

在我询问有关filling space between two curve lines with gradient的前两天。
从那以后,我在代码中做了很多更改-现在我正在使用着色器。结果几乎是我所需要的。但!同样,我在一个 Controller 中同时使用多个OpenGL View 时遇到问题,但它们必须彼此绝对独立。
因此,由于raywenderlich.comcode example from bradley令人难以置信的教程,我有了下一种情况:

  • SoundWaveView.swift类的两个自定义对象(从bradley的OpenGLView.swift改进);
  • opentlView对象的
  • 顶点/片段着色器;
  • 我在其中创建和添加两个SoundWaveView对象(具有相同上下文!!!!)的
  • Controller :

  • C
    override func viewDidLoad() {
    super.viewDidLoad()


    let context = EAGLContext(API: EAGLRenderingAPI.OpenGLES2)

    let viewPos1: CGRect = CGRectMake(0, 150, UIScreen.mainScreen().bounds.size.width, 150);
    let view1 = SoundWaveView(frame: viewPos1, fileName: "Personal Jesus", fileExtention: "mp3", c: context)
    view1.backgroundColor = UIColor.grayColor()
    self.view.addSubview(view1)


    let viewPos2: CGRect = CGRectMake(0, 350, UIScreen.mainScreen().bounds.size.width, 150);
    let view2 = SoundWaveView(frame: viewPos2, fileName: "Imagine", fileExtention: "mp3", c: context)
    view2.backgroundColor = UIColor.blackColor()
    self.view.addSubview(view2)
    }

    每个SoundWaveView对象都会编译着色器,如上面的教程中所示:
        func compileShaders() {

    let vertexShader = compileShader("SimpleVertex", shaderType: GLenum(GL_VERTEX_SHADER))
    let fragmentShader = compileShader("SimpleFragment", shaderType: GLenum(GL_FRAGMENT_SHADER))

    let programHandle: GLuint = glCreateProgram()
    glAttachShader(programHandle, vertexShader)
    glAttachShader(programHandle, fragmentShader)
    glLinkProgram(programHandle)

    var linkSuccess: GLint = GLint()
    glGetProgramiv(programHandle, GLenum(GL_LINK_STATUS), &linkSuccess)
    if (linkSuccess == GL_FALSE) {
    var message = [CChar](count: 256, repeatedValue: CChar(0))
    var length = GLsizei(0)
    glGetProgramInfoLog(programHandle, 256, &length, &message)
    print("Failed to create shader program! : \( String(UTF8String: message) ) ")
    exit(1);
    }

    glUseProgram(programHandle)

    . . . . .
    shaderPeakId = glGetUniformLocation(programHandle, "peakId")

    shaderWaveAmp = glGetUniformLocation(programHandle, "waveAmp");

    glEnableVertexAttribArray(positionSlot)
    glEnableVertexAttribArray(colorSlot)

    glUniform1f(shaderSceneWidth!, Float(self.frame.size.width));
    glUniform1f(shaderSceneHeight!, Float(self.frame.size.height));
    glUniform1i(shaderPeaksTotal!, GLint(total));
    glUniform1i(shaderPeakId!, GLint(position));

    }

    为了渲染音频波,需要将以下值传递给着色器值:A)振幅(我从avaudioplayer获得-完美工作,并且对于我在 Controller 中创建的两个对象,我对两个不同的音轨具有不同的振幅)和B)波数(又名peakId /位置)。

    因此,对于第一个创建的对象(灰色),位置等于1,并且该波必须为红色,并放置在屏幕的左侧。对于第二个对象(黑色),位置为3,则波浪为蓝色,并放置在右侧。 /位置2用于屏幕中心,现在不使用/

    每次音频更新都会导致opengl的更新:
    var waveAmp :Float = 0

    . . . . .

    func updateMeters(){

    player!.updateMeters()
    var normalizedValue = normalizedPowerLevelFromDecibels(player!.averagePowerForChannel(0))

    waveAmp = normalizedValue!
    }

    func render(displayLink: CADisplayLink?) {

    glBlendFunc(GLenum(GL_ONE), GLenum(GL_ONE_MINUS_SRC_ALPHA))
    glEnable(GLenum(GL_BLEND))

    // glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0)
    glClearColor(0, 0, 0, 0)
    glClear(GLenum(GL_COLOR_BUFFER_BIT) | GLenum(GL_DEPTH_BUFFER_BIT))
    glEnable(GLenum(GL_DEPTH_TEST))

    glViewport(0, 0, GLsizei(self.frame.size.width), GLsizei(self.frame.size.height))

    glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)
    glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indexBuffer)

    glVertexAttribPointer(positionSlot, 3, GLenum(GL_FLOAT), GLboolean(UInt8(GL_FALSE)), GLsizei(sizeof(Vertex)), nil)
    glVertexAttribPointer(colorSlot, 4, GLenum(GL_FLOAT), GLboolean(UInt8(GL_FALSE)), GLsizei(sizeof(Vertex)), UnsafePointer<Void>(bitPattern: (sizeof(Float) * 3)))

    glDrawElements(GLenum(GL_TRIANGLE_FAN), GLsizei(Indices.size()), GLenum(GL_UNSIGNED_BYTE), nil)

    glVertexAttribPointer(positionSlot, 3, GLenum(GL_FLOAT), GLboolean(UInt8(GL_FALSE)), GLsizei(sizeof(Vertex)), nil);
    glVertexAttribPointer(colorSlot, 4, GLenum(GL_FLOAT), GLboolean(UInt8(GL_FALSE)), GLsizei(sizeof(Vertex)), UnsafePointer<Void>(bitPattern: (sizeof(Float) * 3)));

    context.presentRenderbuffer(Int(GL_RENDERBUFFER))


    print("position=\(position) waveAmp=\(waveAmp)")
    glUniform1i(shaderPeakId!, GLint(position));
    glUniform1f(shaderWaveAmp!, waveAmp);
    }

    使用print()函数登录:
    position=1  waveAmp=0.209313
    position=3 waveAmp=0.47332
    position=1 waveAmp=0.207556
    position=3 waveAmp=0.446235
    position=1 waveAmp=0.20769
    position=3 waveAmp=0.446235
    position=1 waveAmp=0.246206
    position=3 waveAmp=0.430118

    我希望我将有两个矩形-一个灰色,左边有红色波浪,一个黑色,右边是蓝色。
    但是我有下一个麻烦!渲染在一个(最后一个) View 中进行,并顺序更改:

    enter image description here enter image description here

    请任何人!如何同时使用两个glView?
    或者,也许我需要在一个 View 中使用两个着色器?

    我想完成这个音频任务,并与大家分享。但是我还是不明白这个问题

    最佳答案

    在您发布的SoundWaveView类的代码中,它看起来像该 View 处理了上下文的初始化,上下文的帧缓冲区等等。由于您向两个 View 都发送了相同的EAGLContext,因此意味着正在初始化相同的上下文,然后很可能由第二个 View 重新初始化。这对我来说似乎不对。如果仅为另一个 View 创建单独的上下文,则实际上可能会很好地工作,并且在这两个 View 之间进行渲染时,GPU只会进行上下文切换,并将它们视为单独的应用程序。

    但这不是应该设计这种简单的应用程序的方式。如果要同时在屏幕上绘制两个对象,那当然并不意味着您需要两个单独的 View 。您将必须构建一个系统来处理从每个波形中获取的信息,并将其自动转换为适当的绘图调用。这将充当您的应用程序的迷你绘制引擎。使用这种方法,您甚至可以为更酷的技术和图形编写更多的支持……也许更多的波形,它们各自的不同纹理/颜色,炫酷效果等。

    关于ios - iOS。 OpenGL。同时几个 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39638481/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com