Ios 网间网操作系统。OpenGL。在曲线下用渐变填充区域

Ios 网间网操作系统。OpenGL。在曲线下用渐变填充区域,ios,opengl-es,gradient,Ios,Opengl Es,Gradient,我需要创建一个类似Siri()的声波动画 使用OpenGL,I'v获得了波形: 这是我的密码: @property (strong, nonatomic) EAGLContext *context; @property (strong, nonatomic) GLKBaseEffect *effect; // ..... - (void)setupGL { [EAGLContext setCurrentContext:self.context]; glEnable(

我需要创建一个类似Siri()的声波动画 使用OpenGL,I'v获得了波形:

这是我的密码:

@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);
}
@property(强,非原子)EAGLContext*上下文;
@性质(强、非原子)GLKBaseEffect*效应;
//    .....
-(无效)设置GL{
[EAGLContext setCurrentContext:self.context];
glEnable(GL_CULL_面);
self.effect=[[glkbaseffect alloc]init];
self.effect.useConstantColor=GL_TRUE;
self.effect.constantColor=GLKVector4Make(0.0f、1.0f、0.0f、1.0f);
}
//    .....
-(void)glkView:(glkView*)视图drawInRect:(CGRect)rect{
glClearColor(_curRed,0.0,0.0,1.0);
glClear(GLU颜色缓冲位);
[自生效准备提款];
GLfloat线[1440];
对于(int i=0;i<1440;i+=4){
浮动x=0.002*i-0.75;
浮球K=8.0f;
浮动弧度=度到弧度(i/2);
浮动函数x=0.4*
功率(K/(K+pow(弧度-M_-PI,4.0f)),K)*
cos(弧度-M_-PI);
线[i]=x;
第[i+1]行=func_x;
线[i+2]=x;
行[i+3]=-func_x;
}
GLuint bufferObjectNameArray;
glGenBuffers(1,&bufferObjectNameArray);
glBindBuffer(GL_数组_BUFFER,bufferObjectNameArray);
glBufferData(
GL_数组_缓冲区,
sizeof(线),
行,,
总帐(静态图纸);
GlenableVertexAttributeArray(GLkVertexAttributePosition);
glvertexattributepointer(
GlkVertexAttributePosition,
2.
浮球,
GL_FALSE,
2*4,
无效);
glLineWidth(15.0);
gldrawArray(GL_线,0,360);
}
但是!我很困惑,因为我找不到梯度的任何解。经过长时间的搜索,我甚至强烈怀疑这样的任务是不可能的(因为我认为glkbaseffect*effect.constantColor)。 所以有人能帮我解决这个问题吗? 使用着色器或纹理可以解决此问题(最糟糕的解决方案)


祝福你的答案

虽然这可以通过纹理实现,但我认为最简单的方法是使用OpenGL的默认颜色插值。如果将要绘制的线的顶部顶点设置为浅蓝色,底部顶点设置为深蓝色,GPU将自动在它们之间插入颜色以逐渐改变,并产生您想要的渐变效果

在代码中实现这一点的最简单方法是在缓冲区“线”数组中为线的每个顶点的颜色留出空间,并设置着色器以输出此值。这意味着您必须将此颜色的输入和输出添加到顶点和像素着色器。其思想是将其从顶点传递到像素着色器,并且像素着色器输出未修改的值。硬件为您自动处理颜色之间的插值(!)


许多现代OpenGL教程都有这样做的示例。一个是免费的,另一个是免费的。不过,如果你有钱的话,我最喜欢的关于缓冲区、着色器和管道本身的解释是Graham Sellers的。如果你打算经常使用OpenGL并真正学习它,它将是一个非常宝贵的桌面参考。

虽然这可以通过纹理实现,但我认为最简单的方法是使用OpenGL的默认颜色插值。如果将要绘制的线的顶部顶点设置为浅蓝色,底部顶点设置为深蓝色,GPU将自动在它们之间插入颜色以逐渐改变,并产生您想要的渐变效果

在代码中实现这一点的最简单方法是在缓冲区“线”数组中为线的每个顶点的颜色留出空间,并设置着色器以输出此值。这意味着您必须将此颜色的输入和输出添加到顶点和像素着色器。其思想是将其从顶点传递到像素着色器,并且像素着色器输出未修改的值。硬件为您自动处理颜色之间的插值(!)


许多现代OpenGL教程都有这样做的示例。一个是免费的,另一个是免费的。不过,如果你有钱的话,我最喜欢的关于缓冲区、着色器和管道本身的解释是Graham Sellers的。如果您计划经常使用OpenGL并真正学习它,它将是一个非常宝贵的桌面参考。

非常感谢!!我真的决定按照您的建议使用着色器来完成此任务。但是我在使用几个glview或几个着色器时还有一个问题,我在这里发布了这个问题:也许你知道问题是什么?我想完成我的自定义wave视图并与大家分享)非常感谢!!我真的决定按照您的建议使用着色器来完成此任务。但是我在使用几个glview或几个着色器时还有一个问题,我在这里发布了这个问题:也许你知道问题是什么?我想完成我的自定义波浪视图并与所有人共享)