56299

iOS. OpenGL. Fill area with gradient under curve line

Question:

I need to create a sound wave animation like Siri (<a href="http://www.patentlyapple.com/.a/6a0120a5580826970c01bb08f96fbf970d-pi" rel="nofollow">SiriAnim</a>) With OpenGL I'v got a shape of wave:

<a href="https://i.stack.imgur.com/U6uh5.png" rel="nofollow"><img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/U6uh5.png" data-original="https://i.stack.imgur.com/U6uh5.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /></a>

Here is my code:

@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! I'm confused because i can't find any solutions for gradient. After a lot of time of searching I even have a strong suspicion that such task is impossible (because GLKBaseEffect *effect . constantColor i think). So! Could anyone help me with any solution for this task? Can this problem be solved with shaders or textures (the worst solution)?

Bless you for your answers!

Answer1:

Although this could be done with a texture, I think the easiest way to accomplish this is by using OpenGL's default color interpolation. If you make the top vertex of the lines you're drawing a light blue, and the bottom vertex a darker blue, the GPU will automatically interpolate the colors between them to gradually change, and produce the gradient effect you're looking for.

The easiest way to implement this in your code is to make room in your buffer, the "lines" array, for the color of every single vertex of the line, and set up your shaders to output this value. That means you'll have to add inputs and outputs for this color to your vertex and pixel shaders. The idea is to pass it from the vertex to the pixel shader, and the pixel shader outputs the value unmodified. The hardware handles the interpolation between colors automatically for you(!).

Many modern OpenGL tutorials have examples of doing this. One free online one is from <a href="http://learnopengl.com/#!Getting-started/Shaders" rel="nofollow">LearnOpenGL's Shader tutorial</a>. If you have the money, though, my favorite explanation of buffers, shaders, and the pipeline itself is in Graham Sellers' <a href="http://rads.stackoverflow.com/amzn/click/0672337479" rel="nofollow">OpenGL SuperBible</a>. If you plan on using OpenGL often and really learning it, it's an invaluable desktop reference.

Recommend

  • Coord texture array does not works correctly with glDrawElements
  • iOS. OpenGL. Several views simultaneously
  • Text in OpenGL using SDL_TTF
  • Goertzel algorithm to get the phase?
  • Drawing a partial circle
  • how to draw 3d cylinder with flat shading
  • Proper page navigation
  • Could not find installable ISAM when importing Access table to Excel
  • Tomcat not shutting down when Spring boot app is deployed with ehcache
  • How to give 3D effects to UIImageView/uiview using OpenGL looks like a 3D CUBE
  • DebugDiag and MVC4 gives no usable stacktrace
  • Rails4: To check for no image uploaded with carrierwave is not working when delete the image
  • App engine CPU times when downloading logs
  • IndexAxisValueFormatter not working as expected
  • subs(sinc(K), K, 0) where K is symbol will return NaN. Shouldn't it be 1?
  • valid way to calculate angle between 2 CLLocations?
  • Regex to capture float from string (and replace with the captured float)
  • Python, Bokeh: How to change range of datetime axis
  • Adding Conditionals & Functions to a Math Parser
  • Round number to nearest “nth” based on first non zero
  • Cannot import Firebase sdk in Swift app
  • Rails: Converting from MySQL to PostGres breaks Geokit Distance Calculations?
  • Geometry shader doesn't do anything when fed GL_POINTS
  • Check overlap begin and end time by group in R
  • Getting Coordinates of a Point in a circle
  • C# - Why is Math.Atan(1) != anything near 45
  • Cassandra Startup failure on ARM64 machine (java.lang.NoClassDefFoundError: Could not initialize cla
  • Convert adjacency matrix to a csv file
  • Python sin and cosine giving incorrect values
  • How to deal with data from arff file with python?
  • Weird LEFT OUTER JOIN on Includes eager loading of rails 3
  • How can I use a custom function within an expression using the eval dataframe method?
  • Cryptic error when trying to run POW
  • JavaScript IE rotation transform maths
  • Using Laravel 5.4 pusher
  • Oledb connection string for excel files
  • Mysterious problem with floating point in LISP - time axis generation
  • Uncaught Error: Could not find module `ember-load-initializers`
  • Counter field in MS Access, how to generate?
  • Arrays break string types in Julia