Search code examples
objective-cmacosopenglaudionsopenglview

Draw different shapes on NSOpenGLView in different NSWindow


I work on AudioVisualizer in objective c on Mac OS. I have 2 NSWindows what has NSOpenGLView in it.

enter image description here

If open only 1 NSWindow with NSOpenGLView, it shows shapes without any issues.

But if open 2 NSWindows what has NSOpenGLView on it, only one GLView draws a shape, but the shape is not matched with its audio when play other audio in other NSWindow.

In NSOpenGLViews, it calls redraw method exactly whenever CADisplayLink needs display.

Here is the part related with OpenGLContext.

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

And here is redraw method

[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];

And here is redrawWithPoints Method

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

I want to show different Audio Visualizers in different NSOpenGLViews at same time.

Is it possible to do with OpenGL?


Solution

  • You're drawing using a vertex buffer object and vertex array buffer, but you don't appear to be sharing between the two contexts. That means that when you use the vertex buffer object in the second context, its ID doesn't exist in that context. However, if you use the first context as the shareContext: parameter to the second view's creation of the NSOpenGLContext, then you can share objects between contexts.

    It can help to add calls to glGetError() periodically in your code to alert you to issues like this.