1

我想在OpenGL ES纹理中渲染视频,以便我可以将此纹理应用到我的 iOS 程序中的 3D 表面。为此,我正在使用GPUImage,但它不起作用,输出中似乎没有加载任何纹理。

这是.h代码:

#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>

#import "GPUImage.h"

@interface ViewController : GLKViewController <GPUImageTextureOutputDelegate>
{
    GLuint texture;
    GPUImageMovie* movie;
    GPUImageTextureOutput *output;


    GPUImagePixellateFilter* pixellateFilter;
}

@end

以下是 .m 文件的部分内容:

在里面

- (void)setupGL
{
    [EAGLContext setCurrentContext:self.context];

    [self loadShaders];

    _vertexArrayBuff = generateSphere(0, 0, 0, 10, 20, 10, &_arraySize);

    glEnable(GL_DEPTH_TEST);

    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, _arraySize * sizeof(GLfloat), _vertexArrayBuff, GL_STATIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(12));
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(24));

    glBindVertexArrayOES(0);

    NSString* fileStr = [[NSBundle mainBundle] pathForResource:@"video" ofType:@"mp4"];
    NSURL* fileUrl = [NSURL fileURLWithPath:fileStr];
    movie = [[GPUImageMovie alloc] initWithURL:fileUrl];

    output = [[GPUImageTextureOutput alloc] init];
    output.delegate = self;

    pixellateFilter = [[GPUImagePixellateFilter alloc] init];

    [movie addTarget:pixellateFilter];
    [pixellateFilter addTarget:output];

    [movie startProcessing];
}

使成为

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray);

    // Render the object again with ES2
    glUseProgram(_program);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
    glUniform1i(uniforms[UNIFORM_TEXTUTRE], 0);

    glDrawArrays(GL_TRIANGLES, 0, _arraySize / 8);
}

代表

- (void)newFrameReadyFromTextureOutput:(GPUImageTextureOutput *)callbackTextureOutput;
{
    dispatch_async(dispatch_get_main_queue(), ^{
        texture = callbackTextureOutput.texture;
    });
}

我尝试手动加载纹理并显示它并且它工作,所以着色器和纹理坐标不是问题。

但是当我尝试用它设置纹理时,GPUImage它不再起作用,我的纹理没有显示,而是我有一个黑色的表面。

有谁知道我做错了什么?我遵循了CubeExamplefromGPUImage但它不起作用。

我现在真的需要一些帮助

谢谢!

PS:我的目标是 iOS 6.1,我使用的是 XCode 4.6.2

编辑

这是开头调用的函数的代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[[[GPUImageContext sharedImageProcessingContext] context] sharegroup]];

    if (!self.context) {
        NSLog(@"Failed to create ES context");
    }

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;

    [self setupGL];
}
4

1 回答 1

0

我认为您缺少 CubeExample 示例代码的一个关键部分。您需要使用共享组来获取在 GPUImage 的 OpenGL ES 上下文中创建的纹理以显示在视图的 OpenGL ES 上下文中。

在 CubeExample 中,我没有使用 GLKit,因此我使用以下代码为我的 CAEAGLLayer 托管视图创建了一个上下文:

    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[[[GPUImageContext sharedImageProcessingContext] context] sharegroup]];

这会抓取 GPUImage 的图像处理 OpenGL ES 上下文使用的共享组,并将其用作我的视图渲染上下文的共享组。

我自己并没有用 GLKit 做太多的工作(我更喜欢较低级别的 OpenGL ES,主要是出于习惯),但我相信您在某些时候为您的 GLKView 设置了 OpenGL ES 上下文。您可以在此时插入 GPUImage 共享组,或者在您进行任何 GPUImage 设置或工作之前,您可以使用-useSharegroup:GPUImageContext 的 sharedImageProcessingContext 上的方法以另一种方式设置 GPUImage 以使用视图的上下文的共享组。

于 2013-05-04T23:55:42.140 回答