Пример #1
0
//=================================================================================================
void eve::ogl::Context::updateFormatVersion(void)
{
	const GLubyte *s = glGetString(GL_VERSION);

	if (!(s && s[0] >= '0' && s[0] <= '9' && s[1] == '.' && s[2] >= '0' && s[2] <= '9'))
	{
		if (!s) {
			EVE_LOG_ERROR("OpenGL version string is null.");
		}
		else {
			EVE_LOG_ERROR("Unexpected OpenGL version string format.");
		}
		m_pixelFormat.setVersion(0, 0);
		m_pixelFormat.setProfile(pf_profNoProfile);
		m_pixelFormat.setOption(pf_optDeprecatedFunctions);
		return;
	}

	int32_t major = s[0] - '0';
	int32_t minor = s[2] - '0';
	m_pixelFormat.setVersion(major, minor);

	if (major < 3)
	{
		m_pixelFormat.setProfile(pf_profNoProfile);
		m_pixelFormat.setOption(pf_optDeprecatedFunctions);
	}
	else
	{
		GLint value = 0;
		if (major > 3 || minor >= 2) {
			glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &value);
		}

		switch (value)
		{
		case WGL_CONTEXT_CORE_PROFILE_BIT_ARB:
			m_pixelFormat.setProfile(pf_profCoreProfile);
			break;
		case WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
			m_pixelFormat.setProfile(pf_profCompatibilityProfile);
			break;
		default:
			m_pixelFormat.setProfile(pf_profNoProfile);
			break;
		}

		glGetIntegerv(GL_CONTEXT_FLAGS, &value);
		if (value & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
			m_pixelFormat.setOption(pf_optNoDeprecatedFunctions);
		else
			m_pixelFormat.setOption(pf_optDeprecatedFunctions);
	}
}
Пример #2
0
//=================================================================================================
void eve::ogl::SubContext::init(void)
{
	// Get DC from window handle.
	m_hDC = ::GetDC(m_hWnd);
	if (m_hDC == 0)
	{
		EVE_LOG_ERROR("Paint device cannot be null. GetDC() failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}


	// Apply pixel format to DC.
	if (::SetPixelFormat(m_hDC, eve::ogl::Context::get_pixel_format_ID(), &eve::ogl::Context::get_pixel_format_descriptor()) == 0)
	{
		EVE_LOG_ERROR("Unable to link pixel format to DC, SetPixelFormat() failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}


#ifndef NDEBUG
	static const int contextAttribs[] = { WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, 0 };
#else
	static const int contextAttribs[] = { 0 };
#endif

	// Create context (GLRC).
	m_hGLRC = wglCreateContextAttribsARB(m_hDC, eve::ogl::Context::get_handle(), contextAttribs);
	if (m_hGLRC == 0)
	{
		EVE_LOG_ERROR("Unable to create rendering context, wglCreateContext() failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}

	// Make context current (has to be activated here to enforce DC bound).
	if (::wglMakeCurrent(m_hDC, m_hGLRC) == 0)
	{
		EVE_LOG_ERROR("Unable to attach context, wglMakeCurrent() failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}

	// Init OpenGL extensions for this context.
	eve::ogl::Context::init_OpenGL();

	// Release context.
	if (::wglMakeCurrent(0, 0) == 0)
	{
		EVE_LOG_ERROR("Unable to detach context, wglMakeCurrent(0, 0) failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}
}
Пример #3
0
//=================================================================================================
void eve::ogl::check_frame_buffer(wchar_t * p_pFunction, wchar_t * p_pFile, int32_t p_line, GLuint p_framebufferId)
{
	GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

	if (status != GL_FRAMEBUFFER_COMPLETE)
	{
		std::wstring mess;
		switch (status)
		{
		case GL_FRAMEBUFFER_UNDEFINED:						mess = EVE_TXT("GL_FRAMEBUFFER_UNDEFINED");							break;
		case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:			mess = EVE_TXT("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT");				break;
		case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:  mess = EVE_TXT("GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");		break;
		case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:			mess = EVE_TXT("GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER");			break;
		case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:			mess = EVE_TXT("GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER");			break;
		case GL_FRAMEBUFFER_UNSUPPORTED:					mess = EVE_TXT("GL_FRAMEBUFFER_UNSUPPORTED");						break;
		case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:			mess = EVE_TXT("GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE");			break;

#if !defined(EVE_OS_DARWIN)
		case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:		mess = EVE_TXT("GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS");			break;
#endif
		}

		EVE_LOG_ERROR("OpenGL Error: %s in function %s in file %s at line %d.", mess.c_str(), p_pFunction, p_pFile, p_line);
		EVE_ASSERT_FAILURE;
	}
}
Пример #4
0
//=================================================================================================
void eve::ogl::check_shader_program(wchar_t * p_pFunction, wchar_t * p_pFile, int32_t p_line, GLuint p_programId)
{
	EVE_ASSERT(p_programId != 0);

	GLint link = GL_FALSE;
	glGetProgramiv(p_programId, GL_LINK_STATUS, &link);

	if (link != GL_TRUE)
	{
		int32_t logLength;
		glGetProgramiv(p_programId, GL_INFO_LOG_LENGTH, &logLength);

		size_t size = std::max(logLength, 1);
		char * buf = (char*)eve::mem::malloc(size *sizeof(char));
		glGetProgramInfoLog(p_programId, logLength, NULL, buf);

		wchar_t * wbuf = (wchar_t*)eve::mem::malloc(size * sizeof(wchar_t));
		mbstowcs(wbuf, buf, size);

		EVE_LOG_ERROR("OpenGL Error: in function %s in file %s at line %d Shader program link failed: %s.", p_pFunction, p_pFile, p_line, wbuf);

		eve::mem::free(wbuf);
		eve::mem::free(buf);

		EVE_ASSERT_FAILURE;
	}
}
Пример #5
0
//=============================================================================================
void eve::thr::Lock::lock(void)
{
#if defined(EVE_OS_WIN)
	::EnterCriticalSection(&m_criticalSections);

#elif defined(EVE_OS_DARWIN)
	if (pthread_mutex_lock(&m_mutex) != 0)
	{
		EVE_LOG_ERROR("Unable to lock mutex pthread_mutex_lock() failed.");
		EVE_ASSERT_FAILURE;
	}

#endif
}
Пример #6
0
//=================================================================================================
void eve::thr::Lock::release(void)
{
#if defined(EVE_OS_WIN)
	::DeleteCriticalSection(&m_criticalSections);

#elif defined(EVE_OS_DARWIN)
	if (pthread_mutex_destroy(&m_mutex) != 0) 
	{
		EVE_LOG_ERROR("Unable to release mutex pthread_mutex_destroy() failed.");
		EVE_ASSERT_FAILURE;
	}

#endif
}
Пример #7
0
//=================================================================================================
bool eve::ogl::SubContext::makeCurrent(void)
{
	eve::ogl::Context::get_fence()->lock();

	bool ret = true;

	if (/*eve::ogl::Context::get_handle()*/ m_hGLRC  == ::wglGetCurrentContext())
	{
		EVE_LOG_ERROR("Context already current.");
		ret = false;
	}

	if (ret && (::wglMakeCurrent(m_hDC, m_hGLRC/*eve::ogl::Context::get_handle()*/) == TRUE))
	{
		eve::ogl::SubContext::set_current_context(this);
	}
	else
	{
		EVE_LOG_ERROR("Unable to attach context, wglMakeCurrent() failed %s", eve::mess::get_error_msg().c_str());
		ret = false;
	}

	return ret;
}
Пример #8
0
//=================================================================================================
void eve::thr::Lock::init(void)
{
#if defined(EVE_OS_WIN)
	eve::mem::memset(&m_criticalSections, 0, sizeof(CRITICAL_SECTION));
	::InitializeCriticalSection(&m_criticalSections);

#elif defined(EVE_OS_DARWIN)
	static const pthread_mutexattr_t attr = { PTHREAD_MUTEX_RECURSIVE };
	if (pthread_mutex_init(&m_mutex, &attr) != 0)
	{
		EVE_LOG_ERROR("Unable to create mutex pthread_mutex_init() failed.");
		EVE_ASSERT_FAILURE;
	}

#endif
}
Пример #9
0
//=================================================================================================
bool eve::ogl::SubContext::doneCurrent(void)
{
	bool ret = true;

	if (::wglMakeCurrent(0, 0) == TRUE)
	{
		eve::ogl::SubContext::set_current_context(nullptr);
	}
	else
	{
		EVE_LOG_ERROR("Unable to detach context, wglMakeCurrent(0, 0) failed %s", eve::mess::get_error_msg().c_str());
		ret = false;
	}

	eve::ogl::Context::get_fence()->unlock();

	return ret;
}
Пример #10
0
//=================================================================================================
void eve::ogl::Context::init_OpenGL(void)
{
	glewInit();

	static bool firstLaunch = true;
	if (firstLaunch)
	{
		GLenum err = glGetError();
		if (err != GL_NO_ERROR)
		{
			// Log error
			EVE_LOG_ERROR("OpenGL extensions initialization failed (GLEW).");
			// Create fatal error window and exit app
			eve::sys::notify_fatal_error(EVE_TXT("OpenGL initialization failed.\n \n Please check your hardware and drivers capabilities."));
		}

		// Retrieve OpenGL version
		GLint majorVersion;
		GLint minorVersion;
		glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
		glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
		EVE_LOG_INFO("Detected OpenGL version %d.%d.", majorVersion, minorVersion);

		// Test OpenGL version
		if (majorVersion < EVE_WINDOWS_OPENGL_MAJOR_VERSION)
		{
			// Create fatal error window and exit app
			eve::sys::notify_fatal_error(EVE_TXT("OpenGL initialization failed.\n \n Please check your hardware and drivers capabilities."));
		}
		else
		{
			if (minorVersion < EVE_WINDOWS_OPENGL_MINOR_VERSION)
			{
				// Create fatal error window and exit app
				eve::sys::notify_fatal_error(EVE_TXT("OpenGL initialization failed.\n \n Please check your hardware and drivers capabilities."));
			}
		}

		eve::ogl::init_debug_stream();

		firstLaunch = false;
	}
}
Пример #11
0
//=================================================================================================
void eve::ogl::check_error(wchar_t * p_pFunction, wchar_t * p_pFile, int32_t p_line)
{
	int32_t Error = glGetError();
	if (Error != GL_NO_ERROR)
	{
		std::wstring mess;
		switch (Error)
		{
		case GL_INVALID_ENUM:					mess = EVE_TXT("GL_INVALID_ENUM");					break;
		case GL_INVALID_VALUE:					mess = EVE_TXT("GL_INVALID_VALUE");					break;
		case GL_INVALID_OPERATION:				mess = EVE_TXT("GL_INVALID_OPERATION");				break;
		case GL_INVALID_FRAMEBUFFER_OPERATION:	mess = EVE_TXT("GL_INVALID_FRAMEBUFFER_OPERATION");	break;
		case GL_STACK_OVERFLOW:					mess = EVE_TXT("GL_STACK_OVERFLOW");				break;
		case GL_STACK_UNDERFLOW:				mess = EVE_TXT("GL_STACK_UNDERFLOW");				break;
		case GL_OUT_OF_MEMORY:					mess = EVE_TXT("GL_OUT_OF_MEMORY");					break;
		default:								mess = EVE_TXT("UNKNOWN");							break;
		}

		EVE_LOG_ERROR("OpenGL Error: %s in function %s in file %s at line %d.", mess.c_str(), p_pFunction, p_pFile, p_line);
		EVE_ASSERT_FAILURE;
	}
}
Пример #12
0
Файл: App.cpp Проект: mrvux/Eve
//=================================================================================================
void eve::app::App::init(void)
{
	// Messaging server (log).
	eve::mess::Server::create_instance();
	// OpenGL master context.
	eve::ogl::Context::create_instance();

	// Win32 COM
#if defined(EVE_OS_WIN)
	HRESULT rtn = ::CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE | COINIT_SPEED_OVER_MEMORY);
	if (!SUCCEEDED(rtn)) {
		EVE_LOG_ERROR("Can't initialize Win32 COM CoInitializeEx() failed.");
	}
#endif

	// View container.
	m_pVecViews = new std::vector<eve::sys::View*>();
	// Fence.
	m_pFence	= EVE_CREATE_PTR(eve::thr::SpinLock);

	// Register to application events.
	eve::evt::register_events_application(this);
}
Пример #13
0
//=================================================================================================
void eve::ogl::Context::init(void)
{
	m_pixelFormat = eve::ogl::PixelFormat::default_format();

	// Create dummy window.
	eve::sys::Window * win = eve::sys::Window::create_ptr(0, 0, 1, 1);

	// Initialize OpenGL drawing device.
	m_hDC = ::GetDC(win->getHandle());
	if (m_hDC == 0)
	{
		EVE_LOG_ERROR("Paint device cannot be null. GetDC() failed: %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}

	// Initialize and choose best fitting Pixel Format.
	m_pixelFormatId = this->choosePixelFormat();
	if (m_pixelFormatId == 0)
	{
		EVE_LOG_ERROR("Unable to get pixel format for device.");
		EVE_ASSERT_FAILURE;
	}


	// Apply pixel format to DC.
	if (::SetPixelFormat(m_hDC, m_pixelFormatId, &m_pixelFormatDecriptor) == FALSE)
	{
		EVE_LOG_ERROR("Unable to link pixel format to DC, SetPixelFormat() failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}


	// Create context (GLRC).
	m_hGLRC = ::wglCreateContext(m_hDC);
	if (m_hGLRC == 0)
	{
		EVE_LOG_ERROR("Unable to create rendering context, wglCreateContext() failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}


	// Make context current (has to be activated here to enforce DC bound).
	if (::wglMakeCurrent(m_hDC, m_hGLRC) == 0)
	{
		EVE_LOG_ERROR("Unable to attach context, wglMakeCurrent() failed %s.", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}

	// Init OpenGL extension for this context
	eve::ogl::Context::init_OpenGL();
	// Stock DC auto updated format.
	this->updateFormatVersion();

	// Release context.
	if (::wglMakeCurrent(0, 0) == 0)
	{
		EVE_LOG_ERROR("Unable to detach context, wglMakeCurrent(0, 0) failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}

	// Release dummy window.
	EVE_RELEASE_PTR(win);
}
Пример #14
0
//=================================================================================================
int32_t eve::ogl::Context::choosePixelFormat(void)
{
	BYTE pmDepth = 0;

	// Pixel format descriptor
	m_pixelFormatDecriptor = eve::ogl::PixelFormat::pixelFormatToPfd(&m_pixelFormat);
	// Choose pixel format
	int32_t chosenPfi = ::ChoosePixelFormat(m_hDC, &m_pixelFormatDecriptor);
	if (chosenPfi == 0) 
	{
		EVE_LOG_ERROR("Unable to retrieve pixel format, ChoosePixelFormat() failed %s", eve::mess::get_error_msg().c_str());
		EVE_ASSERT_FAILURE;
	}

	// GDI function ChoosePixelFormat() does not handle overlay and direct-rendering requests
	bool doSearch = (chosenPfi <= 0);
	PIXELFORMATDESCRIPTOR pfd;
	eve::ogl::PixelFormat fmt;
	if (!doSearch)
	{
		::DescribePixelFormat(m_hDC, chosenPfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
		fmt = eve::ogl::PixelFormat::pfdToPixelFormat(&pfd);

		if (m_pixelFormat.hasOverlay() && !fmt.hasOverlay())
			doSearch = true;
		else if (!logEq(m_pixelFormat.directRendering(), fmt.directRendering()))
			doSearch = true;
		else if ((!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) || pfd.cColorBits != pmDepth))
			doSearch = true;
		else if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW))
			doSearch = true;
		else if (!logEq(m_pixelFormat.rgba(), fmt.rgba()))
			doSearch = true;
	}


	if (doSearch)
	{
		int32_t pfiMax		= ::DescribePixelFormat(m_hDC, 0, 0, NULL);
		int32_t bestScore	= -1;
		int32_t bestPfi		= -1;

		for (int32_t pfi = 1; pfi <= pfiMax; pfi++)
		{
			::DescribePixelFormat(m_hDC, pfi, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
			if (!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
				continue;
			if ((!(pfd.dwFlags & PFD_DRAW_TO_BITMAP) || pfd.cColorBits != pmDepth))
				continue;
			if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW))
				continue;

			fmt = eve::ogl::PixelFormat::pfdToPixelFormat(&pfd);
			if (m_pixelFormat.hasOverlay() && !fmt.hasOverlay())
				continue;

			int32_t score = pfd.cColorBits;
			if (logEq(m_pixelFormat.depth(), fmt.depth()))
				score += pfd.cDepthBits;
			if (logEq(m_pixelFormat.alpha(), fmt.alpha()))
				score += pfd.cAlphaBits;
			if (logEq(m_pixelFormat.accum(), fmt.accum()))
				score += pfd.cAccumBits;
			if (logEq(m_pixelFormat.stencil(), fmt.stencil()))
				score += pfd.cStencilBits;
			if (logEq(m_pixelFormat.doubleBuffer(), fmt.doubleBuffer()))
				score += 1000;
			if (logEq(m_pixelFormat.stereo(), fmt.stereo()))
				score += 2000;
			if (logEq(m_pixelFormat.directRendering(), fmt.directRendering()))
				score += 4000;
			if (logEq(m_pixelFormat.rgba(), fmt.rgba()))
				score += 8000;
			if (score > bestScore)
			{
				bestScore = score;
				bestPfi = pfi;
			}
		}

		if (bestPfi > 0)
		{
			// Stock chosen pfi ID
			chosenPfi = bestPfi;
			// Stock selected pixel format
			m_pixelFormat = fmt;
		}
	}

	return chosenPfi;
}
Пример #15
0
//=================================================================================================
std::string eve::io::load_program(const std::string & p_filePath, const char * p_preamble, size_t * p_finalLength)
{
	// locals
	FILE * pFileStream = nullptr;
	size_t szSourceLength;

	// Open source code file.
#if defined(EVE_OS_WIN)   
	if (fopen_s(&pFileStream, p_filePath.c_str(), "rb") != 0)
	{
		// File open failed, path issue?
		EVE_ASSERT_FAILURE;
		EVE_LOG_ERROR("File opening failed, path is %s", eve::str::to_wstring(p_filePath).c_str());
		return NULL;
	}
#else
	pFileStream = fopen(p_filePath.c_str(), "rb");
	if (pFileStream == 0)
	{
		// File open failed, path issue?
		EVE_LOG_ERROR("File opening failed, path is %s", eve::str::to_wstring(p_filePath).c_str());
		EVE_ASSERT_FAILURE;
		return NULL;
	}
#endif


	// Get source code length.
	fseek(pFileStream, 0, SEEK_END);
	szSourceLength = ftell(pFileStream);
	fseek(pFileStream, 0, SEEK_SET);

	// Allocate string buffer.
	size_t szPreambleLength = 0;
	if (p_preamble)
	{
		szPreambleLength = strlen(p_preamble);
	}

	char * cSourceString = (char*)eve::mem::malloc(szSourceLength + szPreambleLength + 1);

	if (p_preamble)
	{
		eve::mem::memcpy(cSourceString, p_preamble, szPreambleLength);
	}

	if (fread((cSourceString)+szPreambleLength, szSourceLength, 1, pFileStream) != 1)
	{
		fclose(pFileStream);
		eve::mem::free(cSourceString);

		// File read failed.
		EVE_ASSERT_FAILURE;
		return NULL;
	}

	// Close the file and retrieve the total length of combined (preamble + source) string.
	fclose(pFileStream);
	if (p_finalLength)
	{
		*p_finalLength = szSourceLength + szPreambleLength;
	}
	cSourceString[szSourceLength + szPreambleLength] = '\0';

	std::string ret(cSourceString);
	eve::mem::free(cSourceString);
	return ret;
}