gpt4 book ai didi

objective-c - 将 IOSurfaces 绘制到另一个 IOSurface

转载 作者:行者123 更新时间:2023-12-05 04:18:27 24 4
gpt4 key购买 nike

如何将一系列 IOSurfaces 绘制到另一个然后将其绘制到屏幕上?我在 MultiGPU 示例项目中尝试过一些来自苹果的源代码,但我设法做的最好的事情就是绘制一个白屏或获得大量的工件并使应用程序崩溃。

我是 openGL 的新手,我不太了解帧缓冲区和纹理的绑定(bind)以及它们如何与 IOSurfaces 交互。

这就是我必须从 IOSurface(直接来自 Apple 的源代码)创建纹理

// Create an IOSurface backed texture
// Create an FBO using the name of this texture and bind the texture to the color attachment of the FBO
- (GLuint)setupIOSurfaceTexture:(IOSurfaceRef)ioSurfaceBuffer {
GLuint name;
CGLContextObj cgl_ctx = (CGLContextObj)[[self openGLContext] CGLContextObj];

glGenTextures(1, &name);

glBindTexture(GL_TEXTURE_RECTANGLE_EXT, name);
CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_EXT, GL_RGBA, 512, 512, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
ioSurfaceBuffer, 0);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// Generate an FBO using the same name with the same texture bound to it as a render target.

glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, name);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_EXT, name, 0);

if(!_depthBufferName) {
glGenRenderbuffersEXT(1, &_depthBufferName);
glRenderbufferStorageEXT(GL_TEXTURE_RECTANGLE_EXT, GL_DEPTH, 512, 512);
}
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_RECTANGLE_EXT, _depthBufferName);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

return name;
}

我有这段代码可以将表面绘制到屏幕上。 (同样来自 Apple 的来源)

// Fill the view with the IOSurface backed texture 
- (void)textureFromCurrentIOSurface {
NSRect bounds = [self bounds];
CGLContextObj cgl_ctx = (CGLContextObj)[[self openGLContext] CGLContextObj];

// Render quad from our iosurface texture
glViewport(0, 0, (GLint)bounds.size.width, (GLint)bounds.size.height);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLfloat)bounds.size.width, 0.0f, (GLfloat)bounds.size.height, -1.0f, 1.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);

glBindTexture(GL_TEXTURE_RECTANGLE_EXT, [[NSApp delegate] currentTextureName]); // Grab the texture from the delegate
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glTexEnvi(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

glTexCoord2f(0.0f, 0.0f);
glVertex2f(0.0f, 0.0f);

glTexCoord2f(512.0f, 0.0f);
glVertex2f((GLfloat)bounds.size.width, 0.0f);

glTexCoord2f(512.0f, 512.0f);
glVertex2f((GLfloat)bounds.size.width, (GLfloat)bounds.size.height);

glTexCoord2f(0.0f, 512.0f);
glVertex2f(0.0f, (GLfloat)bounds.size.height);

glEnd();

glDisable(GL_TEXTURE_RECTANGLE_EXT);
}

在将单个 IOSurface 绘制到屏幕的情况下,这工作正常。我缺少什么来将 IOSurface 绘制到另一个?

假设我有纹理 A、B、C 和 D,我想:

-在特定区域将A绘制到C上,
- 将 B 绘制到不同区域的 C 上(可能与 A 重叠),
- 将 C 绘制到屏幕上。

最佳答案

我使用以下代码解决了这个问题,但是在绘制之前缩放 IOSurface 存在一些小问题。

- (void)renderIOSurface:(IOSurfaceRef)surface toBuffer:(GLuint)buffer atPoint:(CGPoint)point withSize:(CGSize)size {
CGLContextObj cgl_ctx = (CGLContextObj)[[self openGLContext] CGLContextObj];

// Bind framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, buffer);

glViewport(0, 0, TEXWIDE, TEXHIGH);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, TEXWIDE, 0.0, TEXHIGH, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

GLsizei sH = (GLsizei)IOSurfaceGetHeight(surface);
GLsizei sW = (GLsizei)IOSurfaceGetWidth(surface);

// Create texture
GLuint name;
glGenTextures(1, &name);
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, name);
CGLTexImageIOSurface2D(cgl_ctx, GL_TEXTURE_RECTANGLE_EXT, GL_RGBA, sW, sH, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, surface, 0);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);

//glDisable(GL_BLEND);

glBindTexture(GL_TEXTURE_RECTANGLE_EXT, name);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glBegin(GL_QUADS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

glTexCoord2f(0.0f, 0.0f);
glVertex2f(point.x, point.y);

glTexCoord2f(sW, 0.0f);
glVertex2f(point.x + size.width, point.y);

glTexCoord2f(sW, sH);
glVertex2f(point.x + size.width, point.y + size.height);

glTexCoord2f(0.0f, sH);
glVertex2f(point.x, point.y + size.height);

glEnd();

//glDisable(GL_TEXTURE_RECTANGLE_EXT);

// Bindback to normal
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

// Delete the name texture
glDeleteTextures(1, &name);

// [[self openGLContext] flushBuffer];
// This flush is necessary to ensure proper behavior if the MT engine is enabled.
// glFlush();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();
}

关于objective-c - 将 IOSurfaces 绘制到另一个 IOSurface,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14097015/

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