gpt4 book ai didi

ios - 将 CIFilter 应用于 OpenGL 渲染到纹理

转载 作者:技术小花猫 更新时间:2023-10-29 10:52:06 25 4
gpt4 key购买 nike

我正在尝试在我的全屏渲染输出上应用 CoreImage 过滤器,但看起来我遗漏了一些东西,因为我得到的是黑屏输出。

首先我将整个场景绘制到纹理上。然后我从该纹理中创建 CoreImage,我最终绘制并展示了它。但我得到的只是黑屏。我正在遵循 Apple 关于绘制到纹理以及将 CoreImage 与 OpenGLES 集成的指南:WWDC2012 511 和 https://developer.apple.com/library/ios/documentation/3ddrawing/conceptual/opengles_programmingguide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html

相关代码如下:

渲染器:

@interface Renderer () {
EAGLContext* _context;
GLuint _defaultFramebuffer, _drawFramebuffer, _depthRenderbuffer, _colorRenderbuffer, _drawTexture;
GLint _backingWidth, _backingHeight;
CIImage *_coreImage;
CIFilter *_coreFilter;
CIContext *_coreContext;
}

初始化方法:

- (BOOL)initOpenGL
{
_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!_context) return NO;

[EAGLContext setCurrentContext:_context];

glGenFramebuffers(1, &_defaultFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer);

glGenRenderbuffers(1, &_colorRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _colorRenderbuffer);

glGenFramebuffers(1, &_drawFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _drawFramebuffer);

glGenTextures(1, &_drawTexture);
glBindTexture(GL_TEXTURE_2D, _drawTexture);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _drawTexture, 0);

glGenRenderbuffers(1, &_depthRenderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderbuffer);

_coreFilter = [CIFilter filterWithName:@"CIColorInvert"];
[_coreFilter setDefaults];

NSDictionary *opts = @{ kCIContextWorkingColorSpace : [NSNull null] };
_coreContext = [CIContext contextWithEAGLContext:_context options:opts];

return YES;
}

每当图层大小发生变化时分配内存(在初始化和方向变化时):

- (void)resizeFromLayer:(CAEAGLLayer *)layer
{
layer.contentsScale = 1;

glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer);

glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];

glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &_backingWidth);
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &_backingHeight);

// glCheckFramebufferStatus ... SUCCESS

glBindFramebuffer(GL_FRAMEBUFFER, _drawFramebuffer);

glBindTexture(GL_TEXTURE_2D, _drawTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _backingWidth, _backingHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _backingWidth, _backingHeight);

// glCheckFramebufferStatus ... SUCCESS
}

绘制方法:

- (void)render:(Scene *)scene
{
[EAGLContext setCurrentContext:_context];

glBindFramebuffer(GL_FRAMEBUFFER, _drawFramebuffer);

// Draw using GLKit, custom shaders, drawArrays, drawElements
// Now rendered scene is in _drawTexture

glBindFramebuffer(GL_FRAMEBUFFER, _defaultFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderbuffer);

// Create CIImage with our render-to-texture texture
_coreImage = [CIImage imageWithTexture:_drawTexture size:CGSizeMake(_backingWidth, _backingHeight) flipped:NO colorSpace:nil];

// Ignore filtering for now; Draw CIImage to current render buffer
[_coreContext drawImage:_coreImage inRect:CGRectMake(0, 0, _backingWidth, _backingHeight) fromRect:CGRectMake(0, 0, _backingWidth, _backingHeight)];

// Present
[_context presentRenderbuffer:GL_RENDERBUFFER];
}

请注意,绘制场景后,_drawTexture 包含渲染的场景。我使用 Xcode 调试工具(Capture OpenGL ES 框架)对此进行了检查。

编辑:如果我尝试用其他纹理创建 CIImage 然后使用 _drawTexture,它会正确显示。我怀疑当 CIContext 试图通过 CIImage 渲染它时,_drawTexture 可能还没有准备好或者被锁定了。

EDIT2:我还尝试用视口(viewport)清除替换所有绘图代码:

  glViewport(0, 0, _backingWidth, _backingHeight);
glClearColor(0, 0.8, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

结果仍然是黑色。这表明问题可能出在绘制纹理或帧缓冲区上。

最佳答案

我终于找到问题所在了。 iOS 上 2 纹理的非幂必须具有线性过滤和钳位到边缘环绕:

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

我的贴图和屏幕尺寸一样,但我没有设置这四个参数。

对于后代:上面的代码是 OpenGL ES 和 CoreImage 互连的完美示例。只需确保正确初始化纹理即可!

关于ios - 将 CIFilter 应用于 OpenGL 渲染到纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20975434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com