Win32: use native OpenGL drivers, if available.

After this commit, if the target system does have modern OpenGL
drivers installed, ANGLE is configured to use them, bypassing most
translation (shaders still have to be translated from ESSL to GLSL).

If there are no OpenGL drivers, such as if the graphics drivers were
installed via Windows Update, DirectX translation is still used. This
results in a very noticeable startup delay and minor performance
degradation.

In addition it is no longer necessary to build with -DOPENGL=1 to be
able to run the binary in wine; everything works out of the box.
Before, wine's incomplete HLSL translator would crash.

This change required renaming the variable `texture` in shaders,
since it shadows the Core GLSL function with the same name, and ANGLE
translates texture2D() calls to texture() calls.
pull/434/head
whitequark 2019-05-23 10:58:31 +00:00
parent 09212963ed
commit e9b9dca2ca
7 changed files with 53 additions and 20 deletions

View File

@ -187,9 +187,9 @@ if(ENABLE_GUI)
set(ANGLE_STATIC ON CACHE INTERNAL "")
set(ANGLE_ENABLE_D3D9 ON CACHE INTERNAL "")
set(ANGLE_ENABLE_D3D11 ON CACHE INTERNAL "")
set(ANGLE_ENABLE_OPENGL OFF CACHE INTERNAL "")
set(ANGLE_ENABLE_ESSL OFF CACHE INTERNAL "")
set(ANGLE_ENABLE_GLSL OFF CACHE INTERNAL "")
set(ANGLE_ENABLE_OPENGL ON CACHE INTERNAL "")
set(ANGLE_ENABLE_ESSL ON CACHE INTERNAL "")
set(ANGLE_ENABLE_GLSL ON CACHE INTERNAL "")
set(ANGLE_ENABLE_HLSL ON CACHE INTERNAL "")
add_vendored_subdirectory(extlib/angle)
set(OPENGL_LIBRARIES EGL GLESv2)

View File

@ -4,9 +4,9 @@
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec4 color;
uniform sampler2D texture;
uniform sampler2D texture_;
void main() {
if(texture2D(texture, gl_FragCoord.xy / 32.0).a < 0.5) discard;
if(texture2D(texture_, gl_FragCoord.xy / 32.0).a < 0.5) discard;
gl_FragColor = color;
}

View File

@ -4,12 +4,12 @@
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec4 color;
uniform sampler2D texture;
uniform sampler2D texture_;
varying vec2 fragTex;
void main() {
vec4 texColor = texture2D(texture, fragTex);
vec4 texColor = texture2D(texture_, fragTex);
if(texColor.a == 0.0) discard;
gl_FragColor = texColor * color;
}

View File

@ -4,10 +4,10 @@
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec4 color;
uniform sampler2D texture;
uniform sampler2D texture_;
varying vec2 fragTex;
void main() {
gl_FragColor = vec4(color.rgb, color.a * texture2D(texture, fragTex).TEX_ALPHA);
gl_FragColor = vec4(color.rgb, color.a * texture2D(texture_, fragTex).TEX_ALPHA);
}

View File

@ -4,9 +4,9 @@
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec4 color;
uniform sampler2D texture;
uniform sampler2D texture_;
void main() {
if(texture2D(texture, gl_FragCoord.xy / 32.0).TEX_ALPHA < 0.5) discard;
if(texture2D(texture_, gl_FragCoord.xy / 32.0).TEX_ALPHA < 0.5) discard;
gl_FragColor = color;
}

View File

@ -22,7 +22,9 @@
#if HAVE_OPENGL == 3
# define EGLAPI /*static linkage*/
# define EGL_EGLEXT_PROTOTYPES
# include <EGL/egl.h>
# include <EGL/eglext.h>
#endif
#if defined(HAVE_SPACEWARE)
@ -498,9 +500,9 @@ public:
#if HAVE_OPENGL == 1
HGLRC hGlRc = NULL;
#elif HAVE_OPENGL == 3
EGLDisplay eglDisplay = NULL;
EGLSurface eglSurface = NULL;
EGLContext eglContext = NULL;
static EGLDisplay eglDisplay;
EGLSurface eglSurface = EGL_NO_SURFACE;
EGLContext eglContext = EGL_NO_CONTEXT;
#endif
WINDOWPLACEMENT placement = {};
@ -603,10 +605,32 @@ public:
sscheck(hGlRc = wglCreateContext(hDc));
#elif HAVE_OPENGL == 3
ssassert(eglBindAPI(EGL_OPENGL_ES_API), "Cannot bind EGL API");
if(eglDisplay == EGL_NO_DISPLAY) {
ssassert(eglBindAPI(EGL_OPENGL_ES_API), "Cannot bind EGL API");
eglDisplay = eglGetDisplay(hDc);
ssassert(eglInitialize(eglDisplay, NULL, NULL), "Cannot initialize EGL");
EGLBoolean initialized = EGL_FALSE;
for(auto &platformType : {
// Try platform types from least to most amount of software translation required.
std::make_pair("OpenGL ES", EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE),
std::make_pair("OpenGL", EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE),
std::make_pair("Direct3D 11", EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE),
std::make_pair("Direct3D 9", EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE),
}) {
dbp("Initializing ANGLE with %s backend", platformType.first);
EGLint displayAttributes[] = {
EGL_PLATFORM_ANGLE_TYPE_ANGLE, platformType.second,
EGL_NONE
};
eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, hDc,
displayAttributes);
if(eglDisplay != EGL_NO_DISPLAY) {
initialized = eglInitialize(eglDisplay, NULL, NULL);
if(initialized) break;
eglTerminate(eglDisplay);
}
}
ssassert(initialized, "Cannot find a suitable EGL display");
}
EGLint configAttributes[] = {
EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
@ -1324,6 +1348,8 @@ public:
}
};
EGLDisplay WindowImplWin32::eglDisplay = EGL_NO_DISPLAY;
WindowRef CreateWindow(Window::Kind kind, WindowRef parentWindow) {
return std::make_shared<WindowImplWin32>(kind,
std::static_pointer_cast<WindowImplWin32>(parentWindow));

View File

@ -118,6 +118,13 @@ precision highp float;
GLint compiled;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if(!compiled) {
dbp("Failed to compile shader:\n"
"----8<----8<----8<----8<----8<----\n"
"%s\n"
"----8<----8<----8<----8<----8<----\n",
src.c_str());
}
ssassert(compiled, "Cannot compile shader");
return shader;
@ -220,7 +227,7 @@ void MeshRenderer::Init() {
{ ATTRIB_POS, "pos" },
}
);
fillShader.SetUniformTextureUnit("texture", 0);
fillShader.SetUniformTextureUnit("texture_", 0);
selectedShader = &lightShader;
}
@ -957,8 +964,8 @@ void IndexedMeshRenderer::Init() {
}
);
texShader.SetUniformTextureUnit("texture", 0);
texaShader.SetUniformTextureUnit("texture", 0);
texShader.SetUniformTextureUnit("texture_", 0);
texaShader.SetUniformTextureUnit("texture_", 0);
selectedShader = &colShader;
}