2012-09-11 27 views
7

Tôi đang cố viết lại mã mẫu Apple GLCameraRipple, với hình ảnh làm nền. Trên thực tế tôi đang cố gắng tạo hiệu ứng gợn sóng trên hình ảnh nước bằng cách sử dụng mã này, nhưng mã đang làm việc cho Camera, Thay vào đó tôi chỉ muốn sử dụng một hình ảnh nước đơn giản làm nền thay vì máy ảnh. Bất kỳ hướng nào hay bất kỳ mã mẫu nào cũng sẽ là một trợ giúp lớn. Cảm ơn trước.Làm thế nào tôi có thể viết lại mẫu GLCameraRipple bằng Hình ảnh làm nền?

Trả lời

9

Cách hiệu ứng gợn sóng của máy ảnh hoạt động là nó làm biến dạng tọa độ kết cấu trên lưới tam giác - vì vậy tin tốt là hiệu ứng bạn muốn hoàn toàn tách biệt với kết cấu video; kết cấu của họ chỉ xảy ra là video. Để thực hiện những gì bạn muốn, tất cả những gì bạn cần làm là xóa tất cả mã video của máy ảnh và gắn kết kết cấu của riêng bạn.

Vì vậy, trong viewDidLoad, bạn muốn nhận xét ra [self setupAVCapture], và đi trước và nhận xét ra cả đồng phục kết cấu trong SetupGL, vì bạn sẽ chỉ sử dụng một (hai dòng là glUniform1i(uniforms[UNIFORM_Y], 0);, glUniform1i(uniforms[UNIFORM_UV], 1);), và sau đó tạo & ràng buộc của bạn kết cấu riêng.

GLKit là cách nhanh nhất để hoàn thành công việc như thế này. GLKit ẩn rất nhiều cuộc gọi hàm OpenGL từ bạn, nhưng rất nhanh, hiệu quả là &.

//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); 

Bây giờ bạn đã mất một số thiết lập rất quan trọng được bao gồm trong setupAVCapture. Vì vậy, hãy đặt nó vào sau mã trên trong 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]; 
} 

Và cuối cùng, bạn sẽ phải thay đổi trình đổ bóng phân đoạn một chút.

Mở Shader.fsh và thay đổi chức năng chính như sau:

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

Dù sao, đó phải làm điều đó. Thật thú vị khi thử nghiệm với RippleModel & xem loại hiệu ứng nào bạn có thể thực hiện.

+2

Câu trả lời tuyệt vời jankins, hoạt động này giống như một sự quyến rũ! Câu trả lời này phải được đánh dấu là được chấp nhận. –

+1

Cảm ơn jankin, điều này phải được đánh dấu là đã chấp nhận – Andrea

+0

Câu trả lời rất không đầy đủ – rraallvv

Các vấn đề liên quan