2016-09-22 64 views
0

前幾天我問filling space between two curve lines with gradient。 因爲我已經改變了很多在我的代碼 - 現在我使用着色器。結果幾乎是我需要的。但!再次,我有一個控制器同時使用多個OpenGL視圖的問題,但它們之間必須完全獨立。 因此,得益於raywenderlich.comcode example from bradley令人難以置信的教程中,我旁邊的情況:iOS。 OpenGL的。幾個觀點同時

  • 二級SoundWaveView.swift(從布拉德利OpenGLView.swift改善)的自定義對象;
  • openglView對象的頂點/片段着色器;
  • 控制器,其中i創建並添加兩個SoundWaveView對象(具有相同的上下文!!!!!):

Ç

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

} 

對於渲染音頻波需要傳遞到shader值A)振幅(我是從avaudioplayer讓他們 - 它的工作完美,兩個對象我創建控制器我有兩個不同的軌道不同的幅度)和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 

我期待我會有兩個矩形 - 一個灰色,左邊是紅色波浪,另一個是黑色,右邊是藍色的線。 但我有下一個麻煩!渲染髮生在一個(最後)查看和更改順序:

enter image description hereenter image description here

請任何人!如何同時使用兩個glView? 也許我需要在一個視圖中使用兩個着色器?

我想完成這個音頻波任務,並與大家分享。但我仍然不明白這個問題

回答

0

尋找您發佈的SoundWaveView類的代碼,它看起來像該視圖處理初始化上下文,上下文的幀緩衝區,併爲您更多。由於您向相同的EAGLContext發送了相同的EAGLContext,這意味着相同的上下文正在被初始化,然後可能會被第二個視圖重新初始化。這對我來說並不合適。如果您爲其他視圖創建一個單獨的上下文,它可能實際上可以正常工作,並且GPU在這兩個視圖之間進行渲染時只會進行上下文切換,並將它們視爲單獨的應用程序。

但是,這不是應該如此簡單的應用程序設計。如果您希望同時在屏幕上繪製兩個對象,那當然並不意味着您需要兩個單獨的視圖。您將不得不建立一個系統來處理從每個波形中獲取信息並自動將其轉換爲適當的繪圖調用。這將作爲您的應用程序的迷你引擎。通過這種方法,您可以爲更酷的技術和繪圖編寫更多的支持......也許更多的波形,其中每個都有不同的紋理/顏色,很酷的效果等等。