简体   繁体   English

GPUImage渲染到OpenGL ES纹理不起作用

[英]GPUImage render to OpenGL ES texture does not work

I would like to render a video in an OpenGL ES texture so that I can apply this texture to a 3D surface in my iOS program. 我想用OpenGL ES纹理渲染视频,以便可以在iOS程序中将此纹理应用于3D表面。 To do that I'm using GPUImage , but it does not work, no texture seems to be loaded in the output. 为此,我正在使用GPUImage ,但是它不起作用,输出中似乎没有纹理加载。

Here is the .h code : 这是.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

And here are parts of the.m file : 这是.m文件的一部分:

Init 在里面

- (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];
}

Render 渲染

- (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);
}

Delegate 代表

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

I tried to manually load a texture and display it and it worked so the shaders and texture coordinates are not the issue. 我尝试手动加载并显示纹理,并且它可以正常工作,因此着色器和纹理坐标不是问题。

But when I try to set the texture with GPUImage it does not work any more, my texture is not displayed, instead I have a black surface. 但是,当我尝试使用GPUImage设置纹理不再起作用时,我的纹理不会显示,而是有黑色表面。

Does anyone know what I did wrong? 有人知道我做错了吗? I followed the CubeExample from GPUImage but it does not work. 我遵循了CubeExampleGPUImage但是它不起作用。

I really need some help now 我现在真的需要一些帮助

Thank you! 谢谢!

PS: I'm targeting iOS 6.1 and I'm using XCode 4.6.2 PS:我的目标是iOS 6.1,而我使用的是XCode 4.6.2

EDIT 编辑

Here is the code of the function called at beginning : 这是开始时调用的函数的代码:

- (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];
}

I think you're missing one critical part of the CubeExample sample code. 我认为您缺少CubeExample示例代码的关键部分。 You need to use a share group to get textures created in GPUImage's OpenGL ES context to appear in your view's OpenGL ES context. 您需要使用共享组来获取在GPUImage的OpenGL ES上下文中创建的纹理,以使其出现在视图的OpenGL ES上下文中。

In the CubeExample, I'm not using GLKit, so I create a context for my CAEAGLLayer-hosting view using the following code: 在CubeExample中,我没有使用GLKit,所以我使用以下代码为CAEAGLLayer-hosting视图创建上下文:

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

This grabs the share group used by GPUImage's image processing OpenGL ES context and uses that as a share group for the rendering context for my view. 这将获取GPUImage的图像处理OpenGL ES上下文使用的共享组,并将其用作我的视图渲染上下文的共享组。

I haven't done much work with GLKit myself (I've preferred lower-level OpenGL ES, mainly out of habit), but I believe you set up the OpenGL ES context for your GLKView at some point. 我本人并未对GLKit进行太多工作(我倾向于使用低级OpenGL ES,主要是出于习惯),但我相信您有时会为GLKView设置OpenGL ES上下文。 You could insert the GPUImage share group at that point, or before you do any GPUImage setup or work, you could use the -useSharegroup: method on GPUImageContext's sharedImageProcessingContext to go the other way and set GPUImage to use your view's context's share group. 您可以在那时插入GPUImage共享组,或者在执行任何GPUImage设置或工作之前,可以使用GPUImageContext的sharedImageProcessingContext上的-useSharegroup:方法进行另一种设置,并将GPUImage设置为使用视图上下文的共享组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM