Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I rewrite the GLCameraRipple sample with Image as background?

I am trying to rewrite the Apple Sample GLCameraRipple code, with image as a background. Actually i am trying to create ripple effect on water image using this code, but code is working for Camera, Instead i just want to use a simple water image as background instead of camera. Any direction or any sample code will be a great help. Thanks in advance.

like image 734
Varun Nagpal Avatar asked Sep 11 '12 14:09

Varun Nagpal


1 Answers

The way the camera rippling effect works is it deforms texture coordinates on a grid of triangles -- so the good news is that the effect you want is quite separate from the video texture; their texture just happens to be a video. To accomplish what you want, all you'd have to do is remove all the camera video code, and bind your own texture.

So in viewDidLoad, you'd comment out [self setupAVCapture], and go ahead and comment out both texture uniforms in SetupGL, since you'll only use one (the two lines are glUniform1i(uniforms[UNIFORM_Y], 0);, glUniform1i(uniforms[UNIFORM_UV], 1);), and then create & bind your own texture.

GLKit is the fastest way to get something like this done. GLKit hides a lot of the OpenGL function calls from you, but is very fast & effective.

//create the GLKTextureInfo object
NSError *error;
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:GLKTextureLoaderOriginBottomLeft];
GLKTextureInfo *texture = [GLKTextureLoader textureWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"image" ofType:@"png"] options:options error:&error];
if (error) NSLog(@"Ripple FRONT TEXTURE ERROR: %@", error);

//bind the texture to texture unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture.target, texture.name);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

Now you've lost some very important setup that was included in setupAVCapture. So put it in after the above code in viewDidLoad:

if (_ripple == nil ||
    texture.width != _textureWidth ||
    texture.height != _textureHeight)
{
    _textureWidth = texture.width;
    _textureHeight = texture.height;

    _ripple = [[RippleModel alloc] initWithScreenWidth:_screenWidth
                                          screenHeight:_screenHeight
                                            meshFactor:_meshFactor
                                           touchRadius:5
                                          textureWidth:_textureWidth
                                         textureHeight:_textureHeight];

    [self setupBuffers];
}

And last, you'll have to change the fragment shader a bit.

Open up Shader.fsh and change the main function to this:

void main()
{
    gl_FragColor = texture2D(SamplerY, texCoordVarying);
}

Anyway, that ought to do it. It's super fun to experiment with the RippleModel & see what kind of whacky effects you can make.

like image 50
jankins Avatar answered Nov 10 '22 21:11

jankins