gpt4 book ai didi

macos - NSView 初始化/同步 OpenGL 的正确方法

转载 作者:行者123 更新时间:2023-12-03 17:47:20 25 4
gpt4 key购买 nike

我按照 Apple 的文档创建了一个自定义 OpenGLView,而不是使用 NSOpenGLView。绘图看起来不错,除了我这里似乎有线程同步问题。由于 NSView 应该位于主线程中,那么如何同步线程,我的意思是 CADisplayLink 似乎在不同的线程上工作,因此在旋转或缩放到 3D 场景后,某些节点会保持旧的变换(缓慢变换)直到旋转/缩放完成的。但是,如果我在显示链接绘图中使用 dispatch_sync/dispatch_async 似乎是正确的。但我不确定它会如何损害性能。

Q1:在displaylink cb中使用dispatch_sync是否正确?或者什么是更好的选择?

Q2:另外,我不会绘制全屏 View ,会有 cocoa 控件或可能多个 openglview。由于主线程不是专用于 opengl ,我不知道它如何影响 FPS 或 cocoa 控件。那么是否可以在单独的线程中运行opengl绘图操作?

对于缩放/旋转情况,我有一个解决方案,我向场景或节点添加一个标志(当缩放/旋转更改时),然后在渲染函数中检查该标志,然后应用变换。渲染/绘图似乎也是正确的。但这只是一种情况;将来还会有一些其他问题。所以我需要同步我认为的线程

CVReturn
displaylink_cb(CVDisplayLinkRef CV_NONNULL displayLink,
const CVTimeStamp * CV_NONNULL inNow,
const CVTimeStamp * CV_NONNULL inOutputTime,
CVOptionFlags flagsIn,
CVOptionFlags * CV_NONNULL flagsOut,
void * CV_NULLABLE displayLinkContext) {
dispatch_sync(dispatch_get_main_queue(), ^{
[(__bridge GLView *)displayLinkContext renderOnce];
});

return kCVReturnSuccess;
}

- (void)syncWithCurrentDisplay {
NSOpenGLContext *openGLContext;
CGLContextObj cglContext;
CGLPixelFormatObj cglPixelFormat;
GLint swapInt;

openGLContext = [self openGLContext];
swapInt = 1;

/* Synchronize buffer swaps with vertical refresh rate */
[openGLContext setValues: &swapInt
forParameter: NSOpenGLCPSwapInterval];

/* Create a display link capable of being used with all active displays */
CVDisplayLinkCreateWithActiveCGDisplays(&m_displayLink);

/* Set the renderer output callback function */
CVDisplayLinkSetOutputCallback(m_displayLink,
display_link_cb,
(__bridge void *)self);

/* Set the display link for the current renderer */
cglContext = [openGLContext CGLContextObj];
cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(m_displayLink,
cglContext,
cglPixelFormat);
}

- (void) renderOnce {
NSOpenGLContext *context;
context = [self openGLContext];

[context makeCurrentContext];

/* because display link is threaded */
CGLLockContext([context CGLContextObj]);
[[self delegate] render];
[context flushBuffer];
CGLUnlockContext([context CGLContextObj]);
}

最佳答案

OpenGL 渲染可以发生在任何线程上,只要它一次仅发生在一个线程上即可。仅仅因为您有 NSView 并不意味着您的上下文必须在主线程上呈现。

请参阅下面的示例。渲染是在显示链接的线程上完成的,除了在主线程上发生的 View 帧更改通知期间,因此代码使用锁来渲染主线程上的一帧(这实际上不是必需的,但如果您这样做,锁显示了如何操作)。

https://developer.apple.com/library/content/samplecode/GLFullScreen/Introduction/Intro.html

关于macos - NSView 初始化/同步 OpenGL 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48127518/

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