Cocoa OpenGLView contexts

i have a cocoa app with 2 openglviews. (own subclassed openglViews - like the apple examples)

drawRect:
glViewport(0, 0, (GLsizei) rect.size.width, (GLsizei) rect.size.height);
	
glClear(GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT);


[[self openGLContext] flushBuffer];

the strange thing is: display lists and textures created in openglview A are available in openglView B. i thought these are different contexts ?!?!!?

First of all, you’re adding the two BUFFER_BITs to glClear, when you should be bitwise-ANDing them (COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT).

Secondly, you can create two ‘shared’ contexts which will share object state between them. Please post you context setup code.

Also, note that NSOpenGLView and NSOpenGLContext are two different types. Based on a quick reading of the documentation, it does appear possible to create two NSOpenGLView’s but only one NSOpenGLContext.

I’m not entirely sure how that would work, since I’ve never really used the Cocoa OpenGL interface before.

I bet that you need to call -[NSOpenGLContext makeCurrentContext] before drawing in each view.

For this question, you may also want to try asking on Apple’s OpenGL mailing list, at http://lists.apple.com

@Frogblast: the bitwise add thing doesn’t matter.

i don’t create the context myself. i override the drawRect method of NSOpenGLView. (the context is automatically generated within prepareGL and drawRect in NSOpenGLView)

it does appear possible to create two NSOpenGLView’s but only one NSOpenGLContext.
does this mean that all my textures,lists,vbos,… are automatically shared in all NSOpenGLViews in my app?

No. Unless you pass one context in the share parameter to another context’s constructor, nothing will be shared between them.

What you’re claiming is very peculiar. I suggest you pay close attention to the current context, checking that it is what you think it is at all times.

Why are you using [[self openGLContext] flushBuffer];?

Just use glFlush() or glFinish().

You shouldn’t need to worry about setting the gl context at all if you’re doing all your rendering from within the drawRect() method (or calling other functions from drawRect).

that is incredibly bad advice.

  1. glFlush is almost always unnecessary. It’s really only of use when you have multiple contexts interacting, which the OP wants to avoid.

  2. glFinish incurs a massive performance penalty. You should never call it. Ever.

  3. Those commands will only cause rendering to become visible if you have a single-buffered context, which you never want in a windowed situation. With only a single buffer, half-rendered content can be displayed to the user at any moment. There is no performance penalty for double-buffering.

Yes you’re right Cookie. I’ve just been looked it up in the docs. My project is Cocoa-based on OSX, and I switched to using glFlush() because I heard it was faster - not so! Although I’ve not had any problems using those commands.

I should mention though that every book and tutorial I’ve seen for using OpenGL contexts within cocoa apps has used either glFinish or glFlush.

As for the original posted-problem, check that your display lists have unique ID numbers for each context. It’s possible you’re calling the same lists for each view.

OK, now I’m not so sure. I tried changing glFlush to that flushBuffer call and now my windows don’t redraw correctly. From the docs:

flushBuffer

  • (void)flushBuffer

Copies the back buffer to the front buffer of the receiver. If the receiver is not a double-buffered context, this call does nothing.
If the NSOpenGLPixelFormat used to create the context had a NO backing store attribute (NSOpenGLPFABackingStore), the buffers may be exchanged rather than copied. This is often the case in full-screen mode.

According to the swap interval context attribute (see the table in “Constants” section), the copy may take place during the vertical retrace of the monitor, rather than immediately after flushBuffer is called. An implicit glFlush is done by flushBuffer before it returns. For optimal performance, an application should not call glFlush immediately before calling flushBuffer. Subsequent OpenGL commands can be issued immediately after calling flushBuffer, but are not executed until the buffer copy is completed.

So basically, glFlush() is being called here.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.