PDA

View Full Version : Cocoa OpenGLView contexts



H.Stony
04-17-2006, 08:00 AM
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 ?!?!!?

Frogblast
04-17-2006, 10:41 PM
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.

Frogblast
04-17-2006, 10:43 PM
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

H.Stony
04-18-2006, 10:17 AM
@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?

OneSadCookie
04-20-2006, 01:51 AM
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.

_new_horizon
05-10-2006, 08:09 AM
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).

OneSadCookie
05-11-2006, 02:20 AM
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.

_new_horizon
05-11-2006, 03:26 AM
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.

_new_horizon
05-11-2006, 07:13 PM
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.