opengl in an external window.


    Jul 18 2007 | 12:04 am
    Hello, I am new to Max/MSP external development and I am working on a project that requires launching a window to draw opengl in...and it will track mouse dragging for positioning objects.
    As of right now I have a functioning external that creates a new window and closes it when I free the object. I am trying now to create an opengl context on this window so I can draw to it. I have seen examples using AGL but was wondering if this is possible within the Max SDK since I am likely to be building this project for windows as well. I would like to accomplish this with a single object...which is why I am not using jitter.
    Any help would be greatly appreciated.
    -Trevor

    • Jul 18 2007 | 6:08 am
      Hi Trevor,
      If it's under win xp you're working, here are two functions which may help.
      They are from the source code of one of my objects (the object struct is
      t_gol). If you need any more, I can send you the source.
      Aengus.
      void InitGLWindow(t_gol *x)
      {
      BOOL ok = false;
      int PixelFormat;
      PIXELFORMATDESCRIPTOR pfd = {
      sizeof(PIXELFORMATDESCRIPTOR),
      1,
      PFD_DRAW_TO_WINDOW | // Draw to window (not bitmap)
      PFD_SUPPORT_OPENGL | // Support OpenGL calls
      PFD_DOUBLEBUFFER, // Double -buffered mode
      PFD_TYPE_RGBA, // RGBA Color mode
      24, // Want 24bit color
      0,0,0,0,0,0, // Not used to select mode
      0,0, // Not used to select mode
      0,0,0,0,0, // Not used to select mode
      32, // Size of depth buffer
      0, // Not used to select mode
      0, // Not used to select mode
      PFD_MAIN_PLANE, // Draw in main plane
      0, // Not used to select mode
      0,0,0 // Not used to select mode
      };
      wind_vis(x->wind); // must be called before PixelFormat is set
      x->hWnd = wind_gethwnd(x->wind); // Max SDK function to get hWnd for
      windows programming
      // subclassing stuff
      x->oldproc = (WNDPROC)SetWindowLong(x->hWnd, GWL_WNDPROC,
      (LONG)MyOwnWndProc);
      x->hDC=GetDC(x->hWnd);
      PixelFormat=ChoosePixelFormat(x->hDC,&pfd);
      SetPixelFormat(x->hDC,PixelFormat,&pfd);
      x->hRC=wglCreateContext(x->hDC);
      if(x->hRC == NULL) post("InitGLWindow: wglCreateContext failed - %d",
      GetLastError());
      x->window_is_visible = true;
      SelectClipRgn(x->hDC,NULL);
      ok = wglMakeCurrent(x->hDC,x->hRC);
      if(!ok) post("InitGLWindow: wglMakeCurrent(x->hDC,x->hRC) failed - %d",
      GetLastError());
      // set viewport to window dimensions
      glViewport(0,0,x->win_width, x->win_height);
      // Set clear color to black - this is in Init as long as it does not
      need to change
      glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      }
      LRESULT CALLBACK MyOwnWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
      lParam)
      {
      int xp, yp; // mouse coordinates
      int row, column;
      t_wind *wind = NULL;
      t_gol *x = NULL;
      wind = wind_fromhwnd(hwnd);
      if(wind)
      x=(t_gol*)wind->w_assoc;
      if(x)
      {
      switch(uMsg)
      {
      case WM_LBUTTONDOWN:
      xp = LOWORD(lParam);
      yp = HIWORD(lParam);
      RenderScene(x, GL_SELECT, xp, (x->win_height-yp),
      MOUSECLICK);
      return 0;
      case WM_MOUSEMOVE:
      if(wParam & MK_LBUTTON)
      {
      xp = LOWORD(lParam);
      yp = HIWORD(lParam);
      RenderScene(x, GL_SELECT, xp, (x->win_height-yp),
      MOUSEDRAG);
      return 0;
      }
      }
      }
      if (x && x->oldproc)
      return CallWindowProc(x->oldproc, hwnd, uMsg, wParam, lParam);
      else
      return DefMDIChildProc(hwnd, uMsg, wParam, lParam);
      }
      ____________________
      www.am-process.org
      On 7/18/07, Trevor Muzzy
      wrote:
      >
      >
      > Hello, I am new to Max/MSP external development and I am working on a
      > project that requires launching a window to draw opengl in...and it will
      > track mouse dragging for positioning objects.
      >
      > As of right now I have a functioning external that creates a new window
      > and closes it when I free the object. I am trying now to create an opengl
      > context on this window so I can draw to it. I have seen examples using AGL
      > but was wondering if this is possible within the Max SDK since I am likely
      > to be building this project for windows as well. I would like to accomplish
      > this with a single object...which is why I am not using jitter.
      >
      > Any help would be greatly appreciated.
      >
      > -Trevor
      >
      --
    • Jul 18 2007 | 7:35 pm
      Thanks for the code Aengus but I'm working on a Mac so much of this code won't work on my machine. I currently have a working implementation using AGL but I was hoping that it would be possible to write code that would work on WinXP and Mac.
    • Jul 19 2007 | 12:12 am
      Right, yeah all the bits that aren't obvious there are windows-specific.
      If you do find a way to write code that will work for both, (or even just
      Mac), please post your findings, as it may be a concern for me too, soon.
      Cheers,
      Aengus.
      On 7/19/07, Trevor Muzzy
      wrote:
      >
      >
      > Thanks for the code Aengus but I'm working on a Mac so much of this code
      > won't work on my machine. I currently have a working implementation using
      > AGL but I was hoping that it would be possible to write code that would work
      > on WinXP and Mac.
      >
      --
      ____________________
      www.am-process.org
    • Jul 20 2007 | 8:19 am
      Hi Trevor, is there any specific reason you don't want to use the Jitter
      ob3d SDK? You don't have to deal with all the platform specific issues
      related to context and window handling. You just hook on to a jit.window/
      jit.gl.render and do whatever low level opengl in your code. You can then
      integrate easily with other jitter(gl) objects as well and all will be cross
      platform from the start. I'm also working on opengl UI things and looked for
      a way to catch the mouse events from a jit.window directly (like
      jitterlistener in js/lua), but couldn't figure it out (if anybody knows I'd
      love to hear about it). As a workaround I simply stream the mouse events
      from the jit.window outlet to my externals input. Works fine. Alternatively
      you can declare your ob3d as a UI object by setting the right flag in the
      setup function, but afaik this will only give you mouse click and drag
      events, no mouseidle info.
      hth, -thijs
      --
      On 7/18/07, Trevor Muzzy
      wrote:
      >
      >
      > Thanks for the code Aengus but I'm working on a Mac so much of this code
      > won't work on my machine. I currently have a working implementation using
      > AGL but I was hoping that it would be possible to write code that would work
      > on WinXP and Mac.
      >