예제 #1
0
//-----------------------------------------------------------------------------
bool Win32Context::initWin32GLContext(HGLRC share_context, const vl::String& title, const vl::OpenGLContextFormat& fmt, int x, int y, int width, int height)
{
    class InOutContract
    {
        Win32Context* mContext;

    public:
        bool mOK;

        InOutContract(Win32Context* context): mContext(context), mOK(true)
        {
            cleanup();
        }

        ~InOutContract()
        {
            if (!mOK)
                cleanup();
        }

        void cleanup()
        {
            // delete HDC
            if (mContext->mHDC)
            {
                DeleteDC(mContext->mHDC);
                mContext->mHDC = NULL;
            }

            // delete HGLRC
            if (mContext->mHGLRC)
            {
                if ( wglDeleteContext(mContext->mHGLRC) == FALSE )
                {
                    MessageBox(NULL, L"OpenGL context cleanup failed.\n"
                               L"The handle either doesn't specify a valid context or the context is being used by another thread.",
                               L"Win32Context::init() error!", MB_OK);
                    mOK = false;
                }
                mContext->mHGLRC = NULL;
            }
        }
    } contract(this);

    if (!contract.mOK)
        return false;

    framebuffer()->setWidth(width);
    framebuffer()->setHeight(height);

    if (!hwnd())
    {
        MessageBox(NULL, L"Cannot create OpenGL context: null HWND.", L"Win32Context::init() error!", MB_OK);
        return contract.mOK = false;
    }

    setWindowTitle(title);

    VL_CHECK(mHDC == NULL);
    mHDC = ::GetDC(hwnd());
    if (!mHDC)
    {
        MessageBox(NULL, L"Device context acquisition failed.", L"Win32Context::init() error!", MB_OK);
        return contract.mOK = false;
    }

    int pixel_format_index = vlWin32::choosePixelFormat(fmt);
    if (pixel_format_index == -1)
    {
        MessageBox(NULL, L"No suitable pixel fmt found.", L"Win32Context::init() error!", MB_OK);
        return contract.mOK = false;
    }

    if (SetPixelFormat(mHDC, pixel_format_index, NULL) == FALSE)
    {
        MessageBox(NULL, L"Pixel fmt setup failed.", L"Win32Context::init() error!", MB_OK);
        return contract.mOK = false;
    }

    // OpenGL rendering context creation

    if (wglCreateContextAttribsARB && mContextAttribs.size() > 1)
    {
        // must be 0-terminated list
        VL_CHECK(mContextAttribs.back() == 0);
        // Creates an OpenGL 3.x / 4.x context with the specified attributes.
        mHGLRC = wglCreateContextAttribsARB(mHDC, 0, &mContextAttribs[0]);
    }
    else
    {
        // Creates default OpenGL context
        mHGLRC = wglCreateContext(mHDC);
    }

    if (!mHGLRC)
    {
        MessageBox(NULL, L"OpenGL rendering context creation failed.", L"Win32Context::init() error!", MB_OK);
        return contract.mOK = false;
    }

    // init GL context and makes it current
    // mic fixme: check this also on all the other GUI bindings.
    if( !initGLContext() )
        return contract.mOK = false;

    if (fmt.multisample() && !Has_GL_ARB_multisample)
        vl::Log::error("WGL_ARB_multisample not supported.\n");

    dispatchInitEvent();

    setPosition(x, y);

    setSize(width, height);

    if (Has_GL_EXT_swap_control)
        wglSwapIntervalEXT( fmt.vSync() ? 1 : 0 );

    if (share_context)
        shareOpenGLResources(share_context);

    if (fmt.fullscreen())
        setFullscreen(true);

    return contract.mOK = true;
}
예제 #2
0
//-----------------------------------------------------------------------------
bool SDLWindow::initSDLWindow(const vl::String& title, const vl::OpenGLContextFormat& info, int x, int y, int width, int height)
{
  if (mScreen || mSDLWindow)
  {
    vl::Log::error("SDL supports only one window at a time.\n");
    VL_TRAP();
    return false;
  }

  framebuffer()->setWidth(width);
  framebuffer()->setHeight(height);
  mSDLWindow = this;

  // init key translation map
  for(int i=0; key_translation_vec[i]; i+=2)
    key_translation_map[ key_translation_vec[i] ] = (vl::EKey)key_translation_vec[i+1];

  // SDL_VIDEO_WINDOW_POS

  char win_pos[32] = {0};
  sprintf ( win_pos, "SDL_VIDEO_WINDOW_POS=%d,%d", x, y );
  SDL_putenv(win_pos);
  // setenv("SDL_VIDEO_CENTERED", "YES", 0);

  // init SDL

  if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
	{
    printf("Unable to init SDL: %s\n", SDL_GetError());
    return false;
  }

  SDL_GL_SetAttribute(SDL_GL_RED_SIZE,   info.rgbaBits().r());
  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, info.rgbaBits().g());
  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,  info.rgbaBits().b());
  SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, info.rgbaBits().a());

  SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE,   info.accumRGBABits().r());
  SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, info.accumRGBABits().g());
  SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,  info.accumRGBABits().b());
  SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, info.accumRGBABits().a());

  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, info.depthBufferBits());
  SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, info.stencilBufferBits());

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, info.doubleBuffer()?1:0);
  SDL_GL_SetAttribute(SDL_GL_STEREO, info.stereo());
  SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, info.multisample()?1:0);
  if (info.multisample())
    SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, info.multisampleSamples());
  SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, info.vSync());

  int bpp = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
  Uint32 flags = SDL_OPENGL | (info.fullscreen() ? SDL_FULLSCREEN : 0);
  width  = width  !=0 ? width  : SDL_GetVideoInfo()->current_w;
  height = height !=0 ? height : SDL_GetVideoInfo()->current_h;
  mScreen = SDL_SetVideoMode( width, height, bpp, flags );
  if (mScreen == 0)
  {
    vl::Log::print( vl::Say("\n  error: SDL_SetVideoMode(%n, %n, %n, %hn) failed: %s\n") << width << height << bpp << flags << SDL_GetError() );
    exit(1);
  }

  // window size problem

  int viewport[4];
  glGetIntegerv(GL_VIEWPORT,  viewport);
  VL_CHECK(viewport[0] == 0);
  VL_CHECK(viewport[1] == 0);
  if (viewport[2] != mScreen->w || viewport[3] != mScreen->h)
  {
    vl::Log::print( vl::Say("\n  warning: OpenGL reported %nx%n as video size but SDL says %nx%n\n") << viewport[2] << viewport[3] << mScreen->w << mScreen->h );
    VL_TRAP()
  }