我需要制作像Siri一样的声波动画(SiriAnim) 使用OpenGL,我得到了波形:
这是我的代码:
@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);
}
BUT!我很困惑,因为我无法找到任何渐变解决方案。经过大量的搜索时间后,我甚至怀疑这样的任务是不可能的(因为GLKBaseEffect *效果。我认为是constantColor)。 所以!有谁可以帮我解决这个任务的任何解决方案? 可以使用着色器或纹理解决此问题(最糟糕的解决方案)?
祝福你的答案!
答案 0 :(得分:1)
尽管可以使用纹理来完成,但我认为最简单的方法是使用OpenGL的默认颜色插值。如果你绘制线条的顶部顶点是浅蓝色,而底部顶点是深蓝色,GPU会自动插入它们之间的颜色以逐渐改变,并产生你正在寻找的渐变效果。 / p>
在代码中实现此功能的最简单方法是在缓冲区中腾出空间,“lines”数组,用于行的每个顶点的颜色,并设置着色器以输出此值。这意味着您必须将此颜色的输入和输出添加到顶点和像素着色器。我们的想法是将它从顶点传递到像素着色器,像素着色器输出未修改的值。硬件会自动为您处理颜色之间的插值(!)。
许多现代OpenGL教程都有这样做的例子。一个免费在线版来自LearnOpenGL's Shader tutorial。但是,如果你有钱,我最喜欢的缓冲区,着色器和管道本身的解释是在格雷厄姆塞勒斯的OpenGL SuperBible。如果您打算经常使用OpenGL并真正学习它,那么这是一个非常宝贵的桌面参考。