在不同的 NSWindow 中在 NSOpenGLView 上绘制不同的形状
Draw different shapes on NSOpenGLView in different NSWindow
我在 objective c Mac OS 从事 AudioVisualizer 方面的工作。
我有 2 个 NSWindows,里面有 NSOpenGLView。
如果只用 NSOpenGLView 打开 1 个 NSWindow,它显示的形状没有任何问题。
但是如果打开2个带有NSOpenGLView的NSWindows,只有一个GLView绘制了一个形状,但是在其他NSWindow播放其他音频时,形状与它的音频不匹配。
在 NSOpenGLViews 中,只要 CADisplayLink 需要显示,它就会调用重绘方法。
这里是与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();
我想同时在不同的 NSOpenGLView 中显示不同的音频可视化工具。
是否可以使用 OpenGL?
您正在使用顶点缓冲区对象和顶点数组缓冲区进行绘制,但您似乎并未在两个上下文之间共享。这意味着当您在第二个上下文中使用顶点缓冲区对象时,它的 ID 在该上下文中不存在。但是,如果您使用第一个上下文作为第二个视图创建 NSOpenGLContext
的 shareContext:
参数,那么您可以在上下文之间共享对象。
在您的代码中定期添加对 glGetError()
的调用,以提醒您注意此类问题。
根据@user1118321的回复,我做了NSOpenGLContextManager来管理OpenglContext。
@interface GOOpenGLContextManager : NSObject
+ (GOOpenGLContextManager*) shared;
@property (nonatomic, strong) NSOpenGLContext* context;
@end
通过使用它,在All NSOpenGLViews中,只使用了一个共享的NSOpenGLContext。
这是我用过的代码。
self.openGLContext = [[NSOpenGLContext alloc] initWithFormat:self.pixelFormat
shareContext:[OpenGLContextManager shared].context];
if ([OpenGLContextManager shared].context == nil) {
[OpenGLContextManager shared].context = self.openGLContext;
}
它就像一个魅力。
我在 objective c Mac OS 从事 AudioVisualizer 方面的工作。 我有 2 个 NSWindows,里面有 NSOpenGLView。
如果只用 NSOpenGLView 打开 1 个 NSWindow,它显示的形状没有任何问题。
但是如果打开2个带有NSOpenGLView的NSWindows,只有一个GLView绘制了一个形状,但是在其他NSWindow播放其他音频时,形状与它的音频不匹配。
在 NSOpenGLViews 中,只要 CADisplayLink 需要显示,它就会调用重绘方法。
这里是与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();
我想同时在不同的 NSOpenGLView 中显示不同的音频可视化工具。
是否可以使用 OpenGL?
您正在使用顶点缓冲区对象和顶点数组缓冲区进行绘制,但您似乎并未在两个上下文之间共享。这意味着当您在第二个上下文中使用顶点缓冲区对象时,它的 ID 在该上下文中不存在。但是,如果您使用第一个上下文作为第二个视图创建 NSOpenGLContext
的 shareContext:
参数,那么您可以在上下文之间共享对象。
在您的代码中定期添加对 glGetError()
的调用,以提醒您注意此类问题。
根据@user1118321的回复,我做了NSOpenGLContextManager来管理OpenglContext。
@interface GOOpenGLContextManager : NSObject
+ (GOOpenGLContextManager*) shared;
@property (nonatomic, strong) NSOpenGLContext* context;
@end
通过使用它,在All NSOpenGLViews中,只使用了一个共享的NSOpenGLContext。
这是我用过的代码。
self.openGLContext = [[NSOpenGLContext alloc] initWithFormat:self.pixelFormat
shareContext:[OpenGLContextManager shared].context];
if ([OpenGLContextManager shared].context == nil) {
[OpenGLContextManager shared].context = self.openGLContext;
}
它就像一个魅力。