2016-09-06 2 views
0

мне нужно создать звуковую волну анимации, как Siri (SiriAnim) С OpenGL I'v получил форму волны:iOS. OpenGL. Заполните область градиентом под кривой линии

enter image description here

Вот мой код:

@property (strong, nonatomic) EAGLContext *context; 
@property (strong, nonatomic) GLKBaseEffect *effect; 

// ..... 

- (void)setupGL { 

    [EAGLContext setCurrentContext:self.context]; 
    glEnable(GL_CULL_FACE); 

    self.effect = [[GLKBaseEffect alloc] init]; 

    self.effect.useConstantColor = GL_TRUE; 
    self.effect.constantColor = GLKVector4Make(0.0f, 1.0f, 0.0f, 1.0f); 
} 

// ..... 

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 

    glClearColor(_curRed, 0.0, 0.0, 1.0); 
    glClear(GL_COLOR_BUFFER_BIT); 

    [self.effect prepareToDraw]; 

    GLfloat line[1440]; 

    for (int i = 0; i < 1440; i += 4) { 

     float x = 0.002*i - 0.75; 

     float K = 8.0f; 
     float radians = DEGREES_TO_RADIANS(i/2); 

     float func_x = 0.4 * 
         pow(K/(K + pow(radians-M_PI,4.0f)), K) * 
         cos(radians-M_PI); 

     line[i] = x; 
     line[i+1] = func_x; 

     line[i+2] = x; 
     line[i+3] = -func_x; 
    } 

    GLuint bufferObjectNameArray; 

    glGenBuffers(1, &bufferObjectNameArray); 

    glBindBuffer(GL_ARRAY_BUFFER, bufferObjectNameArray); 

    glBufferData(
       GL_ARRAY_BUFFER, 
       sizeof(line), 
       line, 
       GL_STATIC_DRAW); 

    glEnableVertexAttribArray(GLKVertexAttribPosition); 

    glVertexAttribPointer(
          GLKVertexAttribPosition, 
          2, 
          GL_FLOAT, 
          GL_FALSE, 
          2*4, 
          NULL); 

    glLineWidth(15.0); 
    glDrawArrays(GL_LINES, 0, 360); 
} 

НО! Я запутался, потому что не могу найти решения для градиента. После большого количества времени поиска у меня даже есть сильное подозрение, что такая задача невозможна (потому что эффект GLKBaseEffect * constantColor я думаю). Итак! Может ли кто-нибудь помочь мне с любым решением для этой задачи? Можно ли решить эту проблему с помощью шейдеров или текстур (худшее решение)?

Благословите вас за ответы!

ответ

1

Хотя это можно сделать с помощью текстуры, я думаю, что самый простой способ добиться этого - использовать интерполяцию цветов по умолчанию OpenGL. Если вы делаете верхнюю вершину линий, на которой вы рисуете светло-голубой, а нижняя вершина - темно-синяя, GPU автоматически интерполирует цвета между ними, чтобы постепенно менять их, и создавая эффект градиента, который вы ищете.

Самый простой способ реализовать это в вашем коде - сделать комнату в вашем буфере, массивом «lines», для цвета каждой отдельной вершины линии и настроить ваши шейдеры для вывода этого значения. Это означает, что вам придется добавлять входы и выходы для этого цвета в вершинные и пиксельные шейдеры. Идея состоит в том, чтобы передать ее из вершины в пиксельный шейдер, а пиксельный шейдер выводит значение без изменений. Аппаратное обеспечение автоматически обрабатывает интерполяцию между цветами (!).

У многих современных учебных пособий OpenGL есть примеры этого. Один бесплатный онлайн-код - от LearnOpenGL's Shader tutorial. Однако, если у вас есть деньги, мое любимое объяснение буферов, шейдеров и самого трубопровода находится в OpenGL SuperBible от Graham Sellers. Если вы планируете часто использовать OpenGL и действительно изучать его, это бесценная справочная система для рабочего стола.

+0

Большое спасибо! Я действительно решил сделать эту задачу, используя шейдеры, как вы рекомендуете. Но у меня есть еще одна проблема с использованием нескольких glView или нескольких шейдеров, эта проблема, которую я опубликовал здесь: http://stackoverflow.com/questions/39638481/ios-opengl-several-views-simultaneous Возможно, вы знаете, в чем проблема? Я хочу закончить свое собственное волновое представление и поделиться им со всеми) – chatlanin

Смежные вопросы