Recommended Posts

Hello,

I'm making a graphical application for Mac OS. I've found several examples of how to create a context on Cocoa form, but all of them involve either NSOpenGlView, or custom view. The question is, is it possible to create a context directly on a window? I'm asking this mostly because of speed concerns, NSOpenGlView clearly renders to a buffer and then draws it on screen.

Share this post


Link to post
Share on other sites

i don't know what NSOpenGlView does, but i can tell you any api is going to render to a buffer, then present that buffer to the screen. presenting to the screen is usually just a simple change of a pointer, so its very fast. If you don't have a backbuffer, and your rendering directly to the front buffer (the buffer currently presenting to the screen), you'll usually end up seeing tears since you may be in the middle of rendering to the buffer while the screen is reading from it

Share this post


Link to post
Share on other sites
1 hour ago, mullich said:

The question is, is it possible to create a context directly on a window?

No, not with modern APIs. NSView subclasses are the drawing and compositing mechanism for Cocoa, so you must use them to do any drawing or compositing, including via OpenGL. Creating a GL context "for a window" in Cocoa is largely meaningless and wouldn't be any "faster." It's like asking to create an OpenGL context for a NSError object.

You can create a custom NSView subclasses though, and build your OpenGL use around that. It isn't any faster per se, but it does afford you more control (at the cost of usability).

As iedoc notes, the whole rendering-to-a-buffer-and-flipping thing is what you want to do, otherwise you get artifacts that you can't control for since you don't have that level of control over the graphics hardware on any modern OS. The flipping is not slow.

If you're really that worried about every little microsecond and you have a good reason to be, you should drop OpenGL anyway. Metal is significantly better at giving you low level control over what matters, and Apple clearly cares much more about it than OpenGL, so this is only going to become more apparent. It is slightly harder to use, however.

Share this post


Link to post
Share on other sites

I have another problem. While resizing, view updates lag behind, so there is white (MacOS 10.8) or black (MacOS 10.12) frame near the border which I'm resizing. I'm using WindowDidResize event, is this correct? I've also tried StartLiveResize and EndLiveResize, but it's even worse.
Oh, and I looked up examples of resizing OpenGL in Cocoa, and they recommend calling glViewport, but it only helps then I'm decreasing size of window, not increasing it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Forum Statistics

    • Total Topics
      628288
    • Total Posts
      2981843
  • Similar Content

    • By grumpyOldDude
      I have strip the code down to barest minimum for clarity
      With the window up and draw rendering correctly, I set the key press to take the 'x' key, but when I press 'x' and print anywhere (and everywhere) to test, nothing prints to console. 
      I scrutinised to see why, but I can't find what is missing.  Can anyone see why its not working? Thanks
      public class PuzzleG extends JFrame implements GLEventListener, KeyListener { private static final long serialVersionUID = 1L; final private int width = 800; final private int height = 600; int numOfUnits; GLU glu= new GLU(); List<ObjVertices> dataArray; public PuzzleG( int units, List<ObjVertices> vertXYZ ) { super(" Puzzle game "); Globals.camera = new Point3D(0.0f, 1.4f, 0.0f); Globals.view = new Point3D(0.0f, -1.0f, -3.0f); GLProfile profile = GLProfile.get(GLProfile.GL2); GLCapabilities capabilities = new GLCapabilities(profile); GLCanvas canvas = new GLCanvas(capabilities); canvas.addGLEventListener(this); this.setName("Minimal OpenGL"); this.getContentPane().add(canvas); this.setSize(width, height); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setVisible(true); this.setResizable(false); dataArray = vertXYZ; numOfUnits = units; canvas.requestFocusInWindow(); } public void play() { } @Override public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glMatrixMode(GL2.GL_MODELVIEW); gl.glLoadIdentity(); glu.gluLookAt( Globals.camera.x, Globals.camera.y, Globals.camera.z, Globals.view.x, Globals.view.y, Globals.view.z, 0.0f, 1.0f, 0.0f); gl.glTranslatef(0.0f, 0.0f, -3.0f); gl.glBegin(GL.GL_LINE_LOOP); /*=========================== START =========================================================== ... draw object vertices ... ============================= end ============================================================ */ gl.glEnd(); gl.glFlush(); } @Override public void dispose(GLAutoDrawable drawable) { if( Globals.c == 'x')System.out.println(" 3333 "); } @Override public void init(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); gl.glClearDepthf(1.0f); gl.glEnable(GL2.GL_DEPTH_TEST); gl.glDepthFunc(GL2.GL_LEQUAL); gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST); gl.glShadeModel(GL2.GL_SMOOTH); gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); if( Globals.c == 'x')System.out.println(" 1111 "); } @Override public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { GL2 gl = drawable.getGL().getGL2(); if (height == 0) height = 1; float aspect = (float)width / height; gl.glViewport(0, 0, width, height); gl.glMatrixMode(GL2.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective( 45, aspect, 0.1f, 100.0f); if( Globals.c == 'x')System.out.println(" 2222 "); } @Override public void keyPressed(KeyEvent e) { Globals.c = e.getKeyChar(); if( Globals.c == 'x'){ System.out.println(" 5555 "); } } @Override public void keyReleased(KeyEvent arg0) { // TODO Auto-generated method stub } @Override public void keyTyped(KeyEvent arg0) { // TODO Auto-generated method stub } } Just for the sake of checking
      I also tried the other key  options as in the code below, but still didn't see any prints to console
      @Override public void keyReleased(KeyEvent e) { Globals.c = e.getKeyChar(); if( Globals.c == 'x'){ System.out.println(" 8888 "); } } @Override public void keyTyped(KeyEvent e) { Globals.c = e.getKeyChar(); if( Globals.c == 'x'){ System.out.println(" 7777 "); } }  
  • Popular Now