【问题标题】:Draw different shapes on NSOpenGLView in different NSWindow在不同的NSWindow中的NSOpenGLView上绘制不同的形状
【发布时间】:2018-10-03 20:20:57
【问题描述】:

我在 Mac OS 上的目标 c 中使用 AudioVisualizer。 我有 2 个 NSWindows,里面有 NSOpenGLView。

如果用 NSOpenGLView 只打开 1 个 NSWindow,它显示的形状没有任何问题。

但是如果打开2个上面有NSOpenGLView的NSWindows,只有一个GLView绘制一个形状,但是在其他NSWindow中播放其他音频时,该形状与它的音频不匹配。

在 NSOpenGLViews 中,只要 CADisplayLink 需要显示,它就会调用 redraw 方法。

这里是与OpenGLContext相关的部分。

self.openGLContext = [[NSOpenGLContext alloc] initWithFormat:self.pixelFormat
                                                shareContext:nil];

这里是redraw 方法

[self.openGLContext makeCurrentContext];
[self.openGLContext lock];

[self redrawWithPoints:self.info->points
            pointCount:self.info->pointCount
            baseEffect:self.baseEffect
    vertexBufferObject:self.info->vbo
     vertexArrayBuffer:self.info->vab
          interpolated:self.info->interpolated
              mirrored:self.shouldMirror
                  gain:self.gain];

[self.openGLContext flushBuffer];
[self.openGLContext unlock];
[NSOpenGLContext clearCurrentContext];

这里是redrawWithPoints方法

glClear(GL_COLOR_BUFFER_BIT);
GLenum mode = interpolated ? GL_TRIANGLE_STRIP : GL_LINE_STRIP;
float interpolatedFactor = interpolated ? 2.0f : 1.0f;
float xscale = 2.0f / ((float)pointCount / interpolatedFactor);
float yscale = 1.0f * gain;
GLKMatrix4 transform = GLKMatrix4MakeTranslation(-1.0f, 0.0f, 0.0f);
transform = GLKMatrix4Scale(transform, xscale, yscale, 1.0f);
baseEffect.transform.modelviewMatrix = transform;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
[baseEffect prepareToDraw];
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition,
                      2,
                      GL_FLOAT,
                      GL_FALSE,
                      sizeof(GOAudioPlotGLPoint),
                      NULL);
glDrawArrays(mode, 0, pointCount);
if (mirrored)
{
    baseEffect.transform.modelviewMatrix = GLKMatrix4Rotate(transform, M_PI, 1.0f, 0.0f, 0.0f);
    [baseEffect prepareToDraw];
    glDrawArrays(mode, 0, pointCount);
}


glFlush();

我想同时在不同的 NSOpenGLViews 中显示不同的 Audio Visualizer。

可以用OpenGL吗?

【问题讨论】:

    标签: objective-c macos opengl audio nsopenglview


    【解决方案1】:

    您正在使用顶点缓冲区对象和顶点数组缓冲区进行绘图,但您似乎没有在两个上下文之间共享。这意味着当您在第二个上下文中使用顶点缓冲区对象时,它的 ID 在该上下文中不存在。但是,如果您使用第一个上下文作为shareContext: 参数来创建第二个视图的NSOpenGLContext,那么您可以在上下文之间共享对象。

    它有助于在代码中定期添加对glGetError() 的调用,以提醒您注意此类问题。

    【讨论】:

    • 谢谢@user1118321。所以你的意思是我需要在 NSOpenGLViews 之间共享 OpenGLContext?如果您有任何示例,请分享。
    • 感谢您的帮助。 @user1118321 我创建了 OpenGLContextManager 用于共享。通过使用它,只创建了一个 openGLContext 并在其他 NSOpenGLViews 上使用它。
    • 这可行。相反,我的意思是所有上下文都在同一个共享组中。并不是所有视图都共享一个上下文,而是它们都将在同一个共享组中创建。详情请见here
    【解决方案2】:

    根据@user1118321的回复,我做了NSOpenGLContextManager来管理OpenglContext。

    @interface GOOpenGLContextManager : NSObject
    
    + (GOOpenGLContextManager*) shared;
    
    @property (nonatomic, strong) NSOpenGLContext* context;
    
    @end
    

    通过使用它,在所有 NSOpenGLViews 中,只使用了一个共享的 NSOpenGLContext。

    这是我使用的代码。

        self.openGLContext = [[NSOpenGLContext alloc] initWithFormat:self.pixelFormat
                                                        shareContext:[OpenGLContextManager shared].context];
    
        if ([OpenGLContextManager shared].context ==  nil) {
            [OpenGLContextManager shared].context = self.openGLContext;
        }
    

    它就像一个魅力。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-21
      • 1970-01-01
      • 1970-01-01
      • 2013-11-23
      • 2012-05-08
      相关资源
      最近更新 更多