/** * Initialize an OpenGL context so that shaders can be compiled. */ static void PlatformInitOpenGL(void*& ContextPtr, void*& PrevContextPtr, int InMajorVersion, int InMinorVersion) { static FPlatformOpenGLContext ShaderCompileContext = {0}; ContextPtr = (void*)wglGetCurrentDC(); PrevContextPtr = (void*)wglGetCurrentContext(); if (ShaderCompileContext.OpenGLContext == NULL && InMajorVersion && InMinorVersion) { PlatformCreateDummyGLWindow(&ShaderCompileContext); // Disable warning C4191: 'type cast' : unsafe conversion from 'PROC' to 'XXX' while getting GL entry points. #pragma warning(push) #pragma warning(disable:4191) if (wglCreateContextAttribsARB == NULL) { // Create a dummy context so that wglCreateContextAttribsARB can be initialized. ShaderCompileContext.OpenGLContext = wglCreateContext(ShaderCompileContext.DeviceContext); check(ShaderCompileContext.OpenGLContext); PlatformMakeGLContextCurrent(&ShaderCompileContext); wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); check(wglCreateContextAttribsARB); wglDeleteContext(ShaderCompileContext.OpenGLContext); } // Create a context so that remaining GL function pointers can be initialized. PlatformCreateOpenGLContextCore(&ShaderCompileContext, InMajorVersion, InMinorVersion, /*InParentContext=*/ NULL); check(ShaderCompileContext.OpenGLContext); PlatformMakeGLContextCurrent(&ShaderCompileContext); if (glCreateShader == NULL) { // Initialize all entry points. #define GET_GL_ENTRYPOINTS(Type,Func) Func = (Type)wglGetProcAddress(#Func); ENUM_GL_ENTRYPOINTS(GET_GL_ENTRYPOINTS); // Check that all of the entry points have been initialized. bool bFoundAllEntryPoints = true; #define CHECK_GL_ENTRYPOINTS(Type,Func) if (Func == NULL) { bFoundAllEntryPoints = false; UE_LOG(LogOpenGLShaderCompiler, Warning, TEXT("Failed to find entry point for %s"), TEXT(#Func)); } ENUM_GL_ENTRYPOINTS(CHECK_GL_ENTRYPOINTS); checkf(bFoundAllEntryPoints, TEXT("Failed to find all OpenGL entry points.")); } // Restore warning C4191. #pragma warning(pop) } PlatformMakeGLContextCurrent(&ShaderCompileContext); }
/** * Loads all OpenGL extensions. * @todo UE4: For now we assume this cannot fail */ void LoadOpenGLExtensions() { #if PLATFORM_WINDOWS if( !bOpenGLExtensionsLoaded ) { //@todo UE4: Assumes the video card supports these for now. bOpenGLExtensionsLoaded = true; glGenBuffers =(PFNGLGENBUFFERSARBPROC) wglGetProcAddress("glGenBuffers"); glBindBuffer =(PFNGLBINDBUFFERARBPROC) wglGetProcAddress("glBindBuffer"); glBufferData =(PFNGLBUFFERDATAARBPROC) wglGetProcAddress("glBufferData"); glDeleteBuffers =(PFNGLDELETEBUFFERSARBPROC) wglGetProcAddress("glDeleteBuffers"); glMapBuffer =(PFNGLMAPBUFFERARBPROC) wglGetProcAddress("glMapBuffer"); glUnmapBuffer =(PFNGLUNMAPBUFFERARBPROC) wglGetProcAddress("glUnmapBuffer"); glDrawRangeElements =(PFNGLDRAWRANGEELEMENTSPROC) wglGetProcAddress("glDrawRangeElements"); glBlendEquation =(PFNGLBLENDEQUATIONPROC) wglGetProcAddress("glBlendEquation"); glActiveTexture =(PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTexture"); glCreateShader =(PFNGLCREATESHADERPROC) wglGetProcAddress("glCreateShader"); glShaderSource =(PFNGLSHADERSOURCEPROC) wglGetProcAddress("glShaderSource"); glCompileShader =(PFNGLCOMPILESHADERPROC) wglGetProcAddress("glCompileShader"); glGetShaderInfoLog =(PFNGLGETSHADERINFOLOGPROC) wglGetProcAddress("glGetShaderInfoLog"); glCreateProgram =(PFNGLCREATEPROGRAMPROC) wglGetProcAddress("glCreateProgram"); glAttachShader =(PFNGLATTACHSHADERPROC) wglGetProcAddress("glAttachShader"); glDetachShader =(PFNGLDETACHSHADERPROC) wglGetProcAddress("glDetachShader"); glLinkProgram =(PFNGLLINKPROGRAMPROC) wglGetProcAddress("glLinkProgram"); glGetProgramInfoLog =(PFNGLGETPROGRAMINFOLOGPROC) wglGetProcAddress("glGetProgramInfoLog"); glUseProgram =(PFNGLUSEPROGRAMPROC) wglGetProcAddress("glUseProgram"); glDeleteShader =(PFNGLDELETESHADERPROC) wglGetProcAddress("glDeleteShader"); glDeleteProgram =(PFNGLDELETEPROGRAMPROC) wglGetProcAddress("glDeleteProgram"); glGetShaderiv =(PFNGLGETPROGRAMIVPROC) wglGetProcAddress("glGetShaderiv"); glGetProgramiv =(PFNGLGETPROGRAMIVPROC) wglGetProcAddress("glGetProgramiv"); glGetUniformLocation =(PFNGLGETUNIFORMLOCATIONPROC) wglGetProcAddress("glGetUniformLocation"); glUniform1f =(PFNGLUNIFORM1FPROC) wglGetProcAddress("glUniform1f"); glUniform2f =(PFNGLUNIFORM2FPROC) wglGetProcAddress("glUniform2f"); glUniform3f =(PFNGLUNIFORM3FPROC) wglGetProcAddress("glUniform3f"); glUniform3fv =(PFNGLUNIFORM3FVPROC) wglGetProcAddress("glUniform3fv"); glUniform4f =(PFNGLUNIFORM4FPROC) wglGetProcAddress("glUniform4f"); glUniform4fv =(PFNGLUNIFORM4FVPROC) wglGetProcAddress("glUniform4fv"); glUniform1i =(PFNGLUNIFORM1IPROC) wglGetProcAddress("glUniform1i"); glUniformMatrix4fv =(PFNGLUNIFORMMATRIX4FVPROC) wglGetProcAddress("glUniformMatrix4fv"); glVertexAttribPointer =(PFNGLVERTEXATTRIBPOINTERPROC) wglGetProcAddress("glVertexAttribPointer"); glBindAttribLocation =(PFNGLBINDATTRIBLOCATIONPROC) wglGetProcAddress("glBindAttribLocation"); glEnableVertexAttribArray =(PFNGLENABLEVERTEXATTRIBARRAYPROC) wglGetProcAddress("glEnableVertexAttribArray"); glDisableVertexAttribArray =(PFNGLDISABLEVERTEXATTRIBARRAYPROC)wglGetProcAddress("glDisableVertexAttribArray"); glGetActiveAttrib =(PFNGLGETACTIVEATTRIBPROC) wglGetProcAddress("glGetActiveAttrib"); glGetActiveUniform =(PFNGLGETACTIVEUNIFORMPROC) wglGetProcAddress("glGetActiveUniform"); glGetAttachedShaders =(PFNGLGETATTACHEDSHADERSPROC) wglGetProcAddress("glGetAttachedShaders"); glGetAttribLocation =(PFNGLGETATTRIBLOCATIONPROC) wglGetProcAddress("glGetAttribLocation"); } #elif PLATFORM_LINUX #define GET_GL_ENTRYPOINTS(Type,Func) { Func = reinterpret_cast<Type>(SDL_GL_GetProcAddress(#Func)); if (NULL == Func) { UE_LOG(LogInit, Fatal, TEXT("Failed to find entry point for %s"), TEXT(#Func)); }} ENUM_GL_ENTRYPOINTS(GET_GL_ENTRYPOINTS); #endif // If extensions are needed for your platform add support for them here }
bool PlatformInitOpenGL() { static bool bInitialized = false; static bool bOpenGLSupported = false; if (!bInitialized) { // Disable warning C4191: 'type cast' : unsafe conversion from 'PROC' to 'XXX' while getting GL entry points. #pragma warning(push) #pragma warning(disable:4191) // Create a dummy context so that wglCreateContextAttribsARB can be initialized. FPlatformOpenGLContext DummyContext; PlatformCreateDummyGLWindow(&DummyContext); DummyContext.OpenGLContext = wglCreateContext(DummyContext.DeviceContext); check(DummyContext.OpenGLContext); ContextMakeCurrent(DummyContext.DeviceContext, DummyContext.OpenGLContext); wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB"); if (wglCreateContextAttribsARB) { int MajorVersion = 0; int MinorVersion = 0; ContextMakeCurrent(NULL,NULL); wglDeleteContext(DummyContext.OpenGLContext); PlatformOpenGLVersionFromCommandLine(MajorVersion, MinorVersion); PlatformCreateOpenGLContextCore(&DummyContext, MajorVersion, MinorVersion, NULL); if (DummyContext.OpenGLContext) { bOpenGLSupported = true; ContextMakeCurrent(DummyContext.DeviceContext, DummyContext.OpenGLContext); } else { UE_LOG(LogRHI,Error,TEXT("OpenGL %d.%d not supported by driver"),MajorVersion,MinorVersion); } } if (bOpenGLSupported) { // Retrieve the OpenGL DLL. void* OpenGLDLL = FPlatformProcess::GetDllHandle(TEXT("opengl32.dll")); if (!OpenGLDLL) { UE_LOG(LogRHI,Fatal,TEXT("Couldn't load opengl32.dll")); } // Initialize entry points required by Unreal from opengl32.dll #define GET_GL_ENTRYPOINTS_DLL(Type,Func) Func = (Type)FPlatformProcess::GetDllExport(OpenGLDLL,TEXT(#Func)); ENUM_GL_ENTRYPOINTS_DLL(GET_GL_ENTRYPOINTS_DLL); // Release the OpenGL DLL. FPlatformProcess::FreeDllHandle(OpenGLDLL); // Initialize all entry points required by Unreal. #define GET_GL_ENTRYPOINTS(Type,Func) Func = (Type)wglGetProcAddress(#Func); ENUM_GL_ENTRYPOINTS(GET_GL_ENTRYPOINTS); ENUM_GL_ENTRYPOINTS_OPTIONAL(GET_GL_ENTRYPOINTS); // Restore warning C4191. #pragma warning(pop) // Check that all of the entry points have been initialized. bool bFoundAllEntryPoints = true; #define CHECK_GL_ENTRYPOINTS(Type,Func) if (Func == NULL) { bFoundAllEntryPoints = false; UE_LOG(LogRHI, Warning, TEXT("Failed to find entry point for %s"), TEXT(#Func)); } ENUM_GL_ENTRYPOINTS_DLL(CHECK_GL_ENTRYPOINTS); ENUM_GL_ENTRYPOINTS(CHECK_GL_ENTRYPOINTS); checkf(bFoundAllEntryPoints, TEXT("Failed to find all OpenGL entry points.")); FString VendorName( ANSI_TO_TCHAR((const ANSICHAR*)glGetString(GL_VENDOR) ) ); if ( VendorName.Contains(TEXT("ATI ")) ) { // Workaround for AMD driver not handling GL_SRGB8_ALPHA8 in glTexStorage2D() properly (gets treated as non-sRGB) glTexStorage1D = NULL; glTexStorage2D = NULL; glTexStorage3D = NULL; } } // The dummy context can now be released. if (DummyContext.OpenGLContext) { ContextMakeCurrent(NULL,NULL); wglDeleteContext(DummyContext.OpenGLContext); } ReleaseDC(DummyContext.WindowHandle, DummyContext.DeviceContext); check(DummyContext.bReleaseWindowOnDestroy); DestroyWindow(DummyContext.WindowHandle); } return bOpenGLSupported; }