Пример #1
0
	void GlContext::create(uint32_t _width, uint32_t _height)
	{
#	if BX_PLATFORM_RPI
		bcm_host_init();
#	endif // BX_PLATFORM_RPI

		m_eglLibrary = eglOpen();

		if (NULL == g_platformData.context)
		{
#	if BX_PLATFORM_RPI
			g_platformData.ndt = EGL_DEFAULT_DISPLAY;
#	endif // BX_PLATFORM_RPI

			BX_UNUSED(_width, _height);
			EGLNativeDisplayType ndt = (EGLNativeDisplayType)g_platformData.ndt;
			EGLNativeWindowType  nwh = (EGLNativeWindowType )g_platformData.nwh;

#	if BX_PLATFORM_WINDOWS
			if (NULL == g_platformData.ndt)
			{
				ndt = GetDC( (HWND)g_platformData.nwh);
			}
#	endif // BX_PLATFORM_WINDOWS

			m_display = eglGetDisplay(ndt);
			BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display);

			EGLint major = 0;
			EGLint minor = 0;
			EGLBoolean success = eglInitialize(m_display, &major, &minor);
			BGFX_FATAL(success && major >= 1 && minor >= 3, Fatal::UnableToInitialize, "Failed to initialize %d.%d", major, minor);

			BX_TRACE("EGL info:");
			const char* clientApis = eglQueryString(m_display, EGL_CLIENT_APIS);
			BX_TRACE("   APIs: %s", clientApis); BX_UNUSED(clientApis);

			const char* vendor = eglQueryString(m_display, EGL_VENDOR);
			BX_TRACE(" Vendor: %s", vendor); BX_UNUSED(vendor);

			const char* version = eglQueryString(m_display, EGL_VERSION);
			BX_TRACE("Version: %s", version); BX_UNUSED(version);

			const char* extensions = eglQueryString(m_display, EGL_EXTENSIONS);
			BX_TRACE("Supported EGL extensions:");
			dumpExtensions(extensions);

			EGLint attrs[] =
			{
				EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,

#	if BX_PLATFORM_ANDROID
				EGL_DEPTH_SIZE, 16,
#	else
				EGL_DEPTH_SIZE, 24,
#	endif // BX_PLATFORM_
				EGL_STENCIL_SIZE, 8,

				EGL_NONE
			};

			EGLint numConfig = 0;
			success = eglChooseConfig(m_display, attrs, &m_config, 1, &numConfig);
			BGFX_FATAL(success, Fatal::UnableToInitialize, "eglChooseConfig");

#	if BX_PLATFORM_ANDROID

			EGLint format;
			eglGetConfigAttrib(m_display, m_config, EGL_NATIVE_VISUAL_ID, &format);
			ANativeWindow_setBuffersGeometry( (ANativeWindow*)g_platformData.nwh, _width, _height, format);

#	elif BX_PLATFORM_RPI
			DISPMANX_DISPLAY_HANDLE_T dispmanDisplay = vc_dispmanx_display_open(0);
			DISPMANX_UPDATE_HANDLE_T  dispmanUpdate  = vc_dispmanx_update_start(0);

			VC_RECT_T dstRect = { 0, 0, int32_t(_width),        int32_t(_height)       };
			VC_RECT_T srcRect = { 0, 0, int32_t(_width)  << 16, int32_t(_height) << 16 };

			DISPMANX_ELEMENT_HANDLE_T dispmanElement = vc_dispmanx_element_add(dispmanUpdate
				, dispmanDisplay
				, 0
				, &dstRect
				, 0
				, &srcRect
				, DISPMANX_PROTECTION_NONE
				, NULL
				, NULL
				, DISPMANX_NO_ROTATE
				);

			s_dispmanWindow.element = dispmanElement;
			s_dispmanWindow.width   = _width;
			s_dispmanWindow.height  = _height;
			nwh = &s_dispmanWindow;

			vc_dispmanx_update_submit_sync(dispmanUpdate);
#	endif // BX_PLATFORM_ANDROID

			m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL);
			BGFX_FATAL(m_surface != EGL_NO_SURFACE, Fatal::UnableToInitialize, "Failed to create surface.");

			const bool hasEglKhrCreateContext = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context");
			const bool hasEglKhrNoError       = !!bx::findIdentifierMatch(extensions, "EGL_KHR_create_context_no_error");

			const uint32_t gles = BGFX_CONFIG_RENDERER_OPENGLES;

			for (uint32_t ii = 0; ii < 2; ++ii)
			{
				bx::StaticMemoryBlockWriter writer(s_contextAttrs, sizeof(s_contextAttrs) );

				EGLint flags = 0;

#	if BX_PLATFORM_RPI
				BX_UNUSED(hasEglKhrCreateContext, hasEglKhrNoError);
#	else
				if (hasEglKhrCreateContext)
				{
					bx::write(&writer, EGLint(EGL_CONTEXT_MAJOR_VERSION_KHR) );
					bx::write(&writer, EGLint(gles / 10) );

					bx::write(&writer, EGLint(EGL_CONTEXT_MINOR_VERSION_KHR) );
					bx::write(&writer, EGLint(gles % 10) );

					flags |= BGFX_CONFIG_DEBUG && hasEglKhrNoError ? 0
						| EGL_CONTEXT_FLAG_NO_ERROR_BIT_KHR
						: 0
						;

					if (0 == ii)
					{
						flags |= BGFX_CONFIG_DEBUG ? 0
							| EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR
//							| EGL_OPENGL_ES3_BIT_KHR
							: 0
							;

						bx::write(&writer, EGLint(EGL_CONTEXT_FLAGS_KHR) );
						bx::write(&writer, flags);
					}
				}
				else
#	endif // BX_PLATFORM_RPI
				{
					bx::write(&writer, EGLint(EGL_CONTEXT_CLIENT_VERSION) );
					bx::write(&writer, 2);
				}

				bx::write(&writer, EGLint(EGL_NONE) );

				m_context = eglCreateContext(m_display, m_config, EGL_NO_CONTEXT, s_contextAttrs);
				if (NULL != m_context)
				{
					break;
				}

				BX_TRACE("Failed to create EGL context with EGL_CONTEXT_FLAGS_KHR (%08x).", flags);
			}

			BGFX_FATAL(m_context != EGL_NO_CONTEXT, Fatal::UnableToInitialize, "Failed to create context.");

			success = eglMakeCurrent(m_display, m_surface, m_surface, m_context);
			BGFX_FATAL(success, Fatal::UnableToInitialize, "Failed to set context.");
			m_current = NULL;

			eglSwapInterval(m_display, 0);
		}

		import();

		g_internalData.context = m_context;
	}
Пример #2
0
void GlContext::create(uint32_t _width, uint32_t _height)
{
    BX_UNUSED(_width, _height);
    XLockDisplay(s_display);

    int major, minor;
    bool version = glXQueryVersion(s_display, &major, &minor);
    BGFX_FATAL(version, Fatal::UnableToInitialize, "Failed to query GLX version");
    BGFX_FATAL( (major == 1 && minor >= 2) || major > 1
                , Fatal::UnableToInitialize
                , "GLX version is not >=1.2 (%d.%d)."
                , major
                , minor
              );

    int32_t screen = DefaultScreen(s_display);

    const char* extensions = glXQueryExtensionsString(s_display, screen);
    BX_TRACE("GLX extensions:");
    dumpExtensions(extensions);

    const int attrsGlx[] =
    {
        GLX_RENDER_TYPE, GLX_RGBA_BIT,
        GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
        GLX_DOUBLEBUFFER, true,
        GLX_RED_SIZE, 8,
        GLX_BLUE_SIZE, 8,
        GLX_GREEN_SIZE, 8,
//			GLX_ALPHA_SIZE, 8,
        GLX_DEPTH_SIZE, 24,
        GLX_STENCIL_SIZE, 8,
        0,
    };

    // Find suitable config
    GLXFBConfig bestConfig = NULL;

    int numConfigs;
    GLXFBConfig* configs = glXChooseFBConfig(s_display, screen, attrsGlx, &numConfigs);

    BX_TRACE("glX num configs %d", numConfigs);

    XVisualInfo* visualInfo = NULL;
    for (int ii = 0; ii < numConfigs; ++ii)
    {
        visualInfo = glXGetVisualFromFBConfig(s_display, configs[ii]);
        if (NULL != visualInfo)
        {
            BX_TRACE("---");
            bool valid = true;
            for (uint32_t attr = 6; attr < BX_COUNTOF(attrsGlx)-1 && attrsGlx[attr] != None; attr += 2)
            {
                int value;
                glXGetFBConfigAttrib(s_display, configs[ii], attrsGlx[attr], &value);
                BX_TRACE("glX %d/%d %2d: %4x, %8x (%8x%s)"
                         , ii
                         , numConfigs
                         , attr/2
                         , attrsGlx[attr]
                         , value
                         , attrsGlx[attr + 1]
                         , value < attrsGlx[attr + 1] ? " *" : ""
                        );

                if (value < attrsGlx[attr + 1])
                {
                    valid = false;
#if !BGFX_CONFIG_DEBUG
                    break;
#endif // BGFX_CONFIG_DEBUG
                }
            }

            if (valid)
            {
                bestConfig = configs[ii];
                BX_TRACE("Best config %d.", ii);
                break;
            }
        }

        XFree(visualInfo);
        visualInfo = NULL;
    }

    XFree(configs);
    BGFX_FATAL(visualInfo, Fatal::UnableToInitialize, "Failed to find a suitable X11 display configuration.");

    BX_TRACE("Create GL 2.1 context.");
    m_context = glXCreateContext(s_display, visualInfo, 0, GL_TRUE);
    BGFX_FATAL(NULL != m_context, Fatal::UnableToInitialize, "Failed to create GL 2.1 context.");

    XFree(visualInfo);

#if BGFX_CONFIG_RENDERER_OPENGL >= 31
    glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress( (const GLubyte*)"glXCreateContextAttribsARB");

    if (NULL != glXCreateContextAttribsARB)
    {
        BX_TRACE("Create GL 3.1 context.");
        const int contextAttrs[] =
        {
            GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
            GLX_CONTEXT_MINOR_VERSION_ARB, 1,
            GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
            0,
        };

        GLXContext context = glXCreateContextAttribsARB(s_display, bestConfig, 0, true, contextAttrs);

        if (NULL != context)
        {
            glXDestroyContext(s_display, m_context);
            m_context = context;
        }
    }
#else
    BX_UNUSED(bestConfig);
#endif // BGFX_CONFIG_RENDERER_OPENGL >= 31

    XUnlockDisplay(s_display);

    import();

    glXMakeCurrent(s_display, s_window, m_context);

    glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalEXT");
    if (NULL != glXSwapIntervalEXT)
    {
        BX_TRACE("Using glXSwapIntervalEXT.");
        glXSwapIntervalEXT(s_display, s_window, 0);
    }
    else
    {
        glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalMESA");
        if (NULL != glXSwapIntervalMESA)
        {
            BX_TRACE("Using glXSwapIntervalMESA.");
            glXSwapIntervalMESA(0);
        }
        else
        {
            glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalSGI");
            if (NULL != glXSwapIntervalSGI)
            {
                BX_TRACE("Using glXSwapIntervalSGI.");
                glXSwapIntervalSGI(0);
            }
        }
    }

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glXSwapBuffers(s_display, s_window);
}
Пример #3
0
	void GlContext::create(uint32_t /*_width*/, uint32_t /*_height*/)
	{
		m_opengl32dll = bx::dlopen("opengl32.dll");
		BGFX_FATAL(NULL != m_opengl32dll, Fatal::UnableToInitialize, "Failed to load opengl32.dll.");

		wglGetProcAddress = (PFNWGLGETPROCADDRESSPROC)bx::dlsym(m_opengl32dll, "wglGetProcAddress");
		BGFX_FATAL(NULL != wglGetProcAddress, Fatal::UnableToInitialize, "Failed get wglGetProcAddress.");

		// If g_bgfxHwnd is NULL, the assumption is that GL context was created
		// by user (for example, using SDL, GLFW, etc.)
		BX_WARN(NULL != g_bgfxHwnd
			, "bgfx::winSetHwnd with valid window is not called. This might "
			  "be intentional when GL context is created by the user."
			);

		if (NULL != g_bgfxHwnd)
		{
			wglMakeCurrent = (PFNWGLMAKECURRENTPROC)bx::dlsym(m_opengl32dll, "wglMakeCurrent");
			BGFX_FATAL(NULL != wglMakeCurrent, Fatal::UnableToInitialize, "Failed get wglMakeCurrent.");

			wglCreateContext = (PFNWGLCREATECONTEXTPROC)bx::dlsym(m_opengl32dll, "wglCreateContext");
			BGFX_FATAL(NULL != wglCreateContext, Fatal::UnableToInitialize, "Failed get wglCreateContext.");

			wglDeleteContext = (PFNWGLDELETECONTEXTPROC)bx::dlsym(m_opengl32dll, "wglDeleteContext");
			BGFX_FATAL(NULL != wglDeleteContext, Fatal::UnableToInitialize, "Failed get wglDeleteContext.");

			m_hdc = GetDC(g_bgfxHwnd);
			BGFX_FATAL(NULL != m_hdc, Fatal::UnableToInitialize, "GetDC failed!");

			// Dummy window to peek into WGL functionality.
			//
			// An application can only set the pixel format of a window one time.
			// Once a window's pixel format is set, it cannot be changed.
			// MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/dd369049%28v=vs.85%29.aspx
			HWND hwnd = CreateWindowA("STATIC"
				, ""
				, WS_POPUP|WS_DISABLED
				, -32000
				, -32000
				, 0
				, 0
				, NULL
				, NULL
				, GetModuleHandle(NULL)
				, 0
				);

			HDC hdc = GetDC(hwnd);
			BGFX_FATAL(NULL != hdc, Fatal::UnableToInitialize, "GetDC failed!");

			HGLRC context = createContext(hdc);

			wglGetExtensionsStringARB  = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
			wglChoosePixelFormatARB    = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
			wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
			wglSwapIntervalEXT         = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");

			if (NULL != wglGetExtensionsStringARB)
			{
				const char* extensions = (const char*)wglGetExtensionsStringARB(hdc);
				BX_TRACE("WGL extensions:");
				dumpExtensions(extensions);
			}

			if (NULL != wglChoosePixelFormatARB
			&&  NULL != wglCreateContextAttribsARB)
			{
				int32_t attrs[] =
				{
					WGL_SAMPLE_BUFFERS_ARB, 0,
					WGL_SAMPLES_ARB, 0,
					WGL_SUPPORT_OPENGL_ARB, true,
					WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
					WGL_DRAW_TO_WINDOW_ARB, true,
					WGL_DOUBLE_BUFFER_ARB, true,
					WGL_COLOR_BITS_ARB, 32,
					WGL_DEPTH_BITS_ARB, 24,
					WGL_STENCIL_BITS_ARB, 8,
					0
				};

				int result;
				uint32_t numFormats = 0;
				do 
				{
					result = wglChoosePixelFormatARB(m_hdc, attrs, NULL, 1, &m_pixelFormat, &numFormats);
					if (0 == result
						||  0 == numFormats)
					{
						attrs[3] >>= 1;
						attrs[1] = attrs[3] == 0 ? 0 : 1;
					}

				} while (0 == numFormats);

				DescribePixelFormat(m_hdc, m_pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &m_pfd);

				BX_TRACE("Pixel format:\n"
					"\tiPixelType %d\n"
					"\tcColorBits %d\n"
					"\tcAlphaBits %d\n"
					"\tcDepthBits %d\n"
					"\tcStencilBits %d\n"
					, m_pfd.iPixelType
					, m_pfd.cColorBits
					, m_pfd.cAlphaBits
					, m_pfd.cDepthBits
					, m_pfd.cStencilBits
					);

				result = SetPixelFormat(m_hdc, m_pixelFormat, &m_pfd);
				// When window is created by SDL and SDL_WINDOW_OPENGL is set SetPixelFormat
				// will fail. Just warn and continue. In case it failed for some other reason
				// create context will fail and it will error out there.
				BX_WARN(result, "SetPixelFormat failed (last err: 0x%08x)!", GetLastError() );

				uint32_t flags = BGFX_CONFIG_DEBUG ? WGL_CONTEXT_DEBUG_BIT_ARB : 0;
				BX_UNUSED(flags);
				int32_t contextAttrs[9] =
				{
#if BGFX_CONFIG_RENDERER_OPENGL >= 31
					WGL_CONTEXT_MAJOR_VERSION_ARB, BGFX_CONFIG_RENDERER_OPENGL / 10,
					WGL_CONTEXT_MINOR_VERSION_ARB, BGFX_CONFIG_RENDERER_OPENGL % 10,
					WGL_CONTEXT_FLAGS_ARB, flags,
					WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
#else
					WGL_CONTEXT_MAJOR_VERSION_ARB, 2,
					WGL_CONTEXT_MINOR_VERSION_ARB, 1,
					0, 0,
					0, 0,
#endif // BGFX_CONFIG_RENDERER_OPENGL >= 31
					0
				};

				m_context = wglCreateContextAttribsARB(m_hdc, 0, contextAttrs);
				if (NULL == m_context)
				{
					// nVidia doesn't like context profile mask for contexts below 3.2?
					contextAttrs[6] = WGL_CONTEXT_PROFILE_MASK_ARB == contextAttrs[6] ? 0 : contextAttrs[6];
					m_context = wglCreateContextAttribsARB(m_hdc, 0, contextAttrs);
				}
				BGFX_FATAL(NULL != m_context, Fatal::UnableToInitialize, "Failed to create context 0x%08x.", GetLastError() );

				BX_STATIC_ASSERT(sizeof(contextAttrs) == sizeof(m_contextAttrs) );
				memcpy(m_contextAttrs, contextAttrs, sizeof(contextAttrs) );
			}