iOS版。 OpenGL的。 几个观点同时

几天之前,我问了两个曲线之间的梯度填充空间 。 由于我已经改变了很多在我的代码 – 现在我使用着色器。 结果几乎是我需要的。 但! 再次我有一个控制器中同时使用几个OpenGL视图的问题,但他们之间必须是绝对独立的。 所以,感谢来自raywenderlich.com的令人难以置信的教程和来自bradley的代码示例,我有下一个情况:

  • SoundWaveView.swift类的两个自定义对象(从Bradley的OpenGLView.swift改进而来);
  • openglView对象的顶点/片段着色器;
  • 控制器,我创build并添加两个SoundWaveView对象(具有相同的上下文!!!!!):

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)); } 

为了渲染audio波需要传递给着色器值为A)幅度(我从avaudioplayer得到它 – 它工作完美,两个对象我创build控制器我有不同的幅度为两个不同的轨道)和B)波数(又名peakId /位置)。

所以对于第一个创build的对象(灰色),位置等于1,这个波必须是红色的,并放置在屏幕的左侧部分。 对于第二个对象(黑色)的位置是3,波浪是蓝色的,并放置在右侧部分。 /位置2是屏幕中心,现在不使用/

每个audio更新都会导致更新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); } 

logging与打印() – function:

 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 

我期望我会有两个矩形 – 左边是一个灰色的红色波浪,右边是一个黑色的蓝色的线条。 但我有下一个麻烦! 渲染发生在一个(最后一个)视图中并依次更改:

在这里输入图像说明 在这里输入图像说明

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

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

看看你发布的SoundWaveView类的代码,它看起来像是处理初始化上下文,上下文的帧缓冲,以及更多。 由于您发送相同的EAGLContext到两个视图,这意味着相同的上下文正在初始化,然后可能重新初始化第二个视图。 这对我来说不太合适。 如果你为另一个视图创build一个单独的上下文,它可能实际上工作正常,并且GPU在这两个视图之间进行渲染时只会进行上下文切换,并将它们视为单独的应用程序。

但是,这不是一个如此简单的应用程序应该如何devise的。 如果你想同时在屏幕上绘制两个对象,那当然不意味着你需要两个单独的视图。 您将不得不build立一个系统来处理从每个波形中获取信息,并自动将其转换为适当的绘图调用。 这将作为您的应用程序的迷你引擎。 通过这种方法,您可以为更酷的技术和绘图编写进一步的支持…也许更多的波形,不同的纹理/颜色,每个都有很酷的效果等等。