OpenGL Mac init context

Hello,

I was trying to setup a new OpenGL context on OS X without using GLSurface. It’s possible to use CGL or NSOpenGL : I tried this code :

[code]soft declare function objc_getClass lib “/usr/lib/libobjc.dylib” ( name as CString ) as ptr
soft declare function NSObject_alloc lib “Foundation” selector “alloc” ( classPtr as ptr ) as ptr
soft declare sub NSObject_release lib “Foundation” selector “release” ( obj as ptr )
soft declare function NSOpenGLView_defaultPixelFormat lib “AppKit” selector “defaultPixelFormat” ( classPtr as ptr ) as ptr
soft declare function NSOpenGLPixelFormat_init lib “AppKit” selector “initWithAttributes:” ( obj as ptr, attrs as ptr ) as ptr
soft declare function NSOpenGLContext_initWithFormat_shareContext lib “AppKit” selector “initWithFormat:shareContext:” ( obj as ptr, pixelFormat as ptr, share as ptr ) as ptr
soft declare sub NSOpenGLContext_setView lib “AppKit” selector “setView:” ( obj as ptr, view as ptr )

dim NSOpenGLContext as ptr = objc_getClass( “NSOpenGLContext” )
dim NSOpenGLView as ptr = objc_getClass( “NSOpenGLView” )

dim attrs as new MemoryBlock( 28 )
attrs.Int32Value( 0 ) = 8 // NSOpenGLPFAColorSize
attrs.Int32Value( 4 ) = 24
attrs.Int32Value( 8 ) = 12 // NSOpenGLPFADepthSize
attrs.Int32Value( 12 ) = 24
attrs.Int32Value( 16 ) = 13 // NSOpenGLPFAStencilSize
attrs.Int32Value( 20 ) = 8
attrs.Int32Value( 24 ) = 0 // terminates the array

dim NSOpenGLPixelFormat as ptr = objc_getClass( “NSOpenGLPixelFormat” )
dim myPixelFormat as ptr = NSOpenGLPixelFormat_init( NSObject_alloc( NSOpenGLPixelFormat ), attrs )

mOpenGLContext = NSOpenGLContext_initWithFormat_shareContext( NSObject_alloc( NSOpenGLContext ), myPixelFormat, nil )
NSOpenGLContext_setView( mOpenGLContext, ptr( self.handle ) )

NSObject_release( myPixelFormat )

raiseEvent open()
raiseEvent paintGL()[/code]

self.handle = Canvas, but I’m missing some information (flush buffer…) & context. Does anybody did a OpenGL Mac setup with CGL or NSOpenGL (not AGL) ?

Thanks

from Daniel P. Bronson link text

I’ve done this before but not that way. Very similar but I don’t quite get that code. So I tried it out and got it working like this…

[code]Class MyOGLView Inherits Canvas

Property mOpenGLContext As Ptr

Sub Open
//the code you’ve posted
End Sub

Sub Paint(g As Graphics, areas() As REALbasic.Rect)
declare sub makeCurrent lib “AppKit” selector “makeCurrentContext” (id As Ptr)
if mOpenGLContext <> nil then
makeCurrent(mOpenGLContext)
RaiseEvent PaintGL
OpenGL.glFlush
end
End Sub

New Event PaintGL()
New Event Open()
End Class

//then drop one on a window with this paint to fill it black

Sub PaintGL()
OpenGL.glViewport 0, 0, me.Width, me.Height
OpenGL.glClearColor 0, 0, 0, 0
OpenGL.glClear OpenGL.GL_COLOR_BUFFER_BIT
End Sub
[/code]

But why go this route instead of OpenGLSurface with Configure?

Thanks Will ! I’ll check it. But OpenGLSurface isn’t limited by the an OpenGL version ? I’m not sure you can set all the parameters as you want such as Stencil buffer etc ??

afaik you can only set the version to Legacy or Core in the attributes. I’ve created Core before but it’s been so long I don’t remember if that was with OpenGLSurface or my class of declares. And I’m not able to make a Core now with either technique :frowning:

Try Creating the attrs MemoryBlock in OpenGLSurface.Configure and return it. There you can set all the same pixel format attributes available: Stencil, Accum, Buffer count, etc. But there is some difference I don’t remember. For example, in one demo I turn on the Accum Buffer. This works in OpenGLSurface as long as DoubleBuffer is also on, but in the declare built version the DoubleBuffer attribute has to be off.

So there is some slight difference but I’m not sure where it comes from. I think you should be able to get Stencil in OpenGLSurface.

OK, I tried those attributes with OpenGLSurface and they work as long as I add DoubleBuffer. Well, it draws black, haven’t actually tested the stencil.

[code]//OpenGLSurface1
Function Configure() As MemoryBlock
dim attrs as new MemoryBlock( 32 )
attrs.Int32Value( 0 ) = 8 // NSOpenGLPFAColorSize
attrs.Int32Value( 4 ) = 24
attrs.Int32Value( 8 ) = 12 // NSOpenGLPFADepthSize
attrs.Int32Value( 12 ) = 24
attrs.Int32Value( 16 ) = 13 // NSOpenGLPFAStencilSize
attrs.Int32Value( 20 ) = 8
attrs.Int32Value( 24 ) = 5 // Double buffer
attrs.Int32Value( 28 ) = 0 // terminates the array
return attrs
End Function

Function Render() As Boolean
OpenGL.glViewport 0, 0, me.Width, me.Height
OpenGL.glClearColor 0,0,0,0
OpenGL.glClear OpenGL.GL_COLOR_BUFFER_BIT
End Function[/code]

Nice, I’m going to check the code. Thanks a lot !

Will, could I make one suggestion for the Configure event, rather use:

dim attrs as new MemoryBlock( 32 ) attrs.Int32Value( 0 ) = 8 // NSOpenGLPFAColorSize attrs.Int32Value( 4 ) = 32 attrs.Int32Value( 8 ) = 12 // NSOpenGLPFADepthSize attrs.Int32Value( 12 ) = 32 attrs.Int32Value( 16 ) = 13 // NSOpenGLPFAStencilSize attrs.Int32Value( 20 ) = 8 attrs.Int32Value( 24 ) = 5 // Double buffer attrs.Int32Value( 28 ) = 0 // terminates the array return attrs

Color depths other than 32 may cause the stencil buffer to operate in software mode (which it did on my Windows machine), which is extremely slow. You could literally see it render pixel for pixel. However, changing to 32-bit mode fixed the problem completely.

Thanks for sharing your code. It helped A LOT with one of my projects.