Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for OpenGL 3 displays on macos #1444

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 24 additions & 14 deletions src/macosx/osxgl.m
Original file line number Diff line number Diff line change
Expand Up @@ -767,8 +767,6 @@ static void osx_set_opengl_pixelformat_attributes(ALLEGRO_DISPLAY_OSX_WIN *dpy)
// Take over the screen.
*a = NSOpenGLPFAScreenMask; a++;
*a = CGDisplayIDToOpenGLDisplayMask(dpy->display_id); a++;
} else {
*a = NSOpenGLPFAWindow; a++;
}

/* Find the requested colour depth */
Expand Down Expand Up @@ -846,9 +844,21 @@ static void osx_set_opengl_pixelformat_attributes(ALLEGRO_DISPLAY_OSX_WIN *dpy)
/* Accelerated is always preferred, so we only set this for required not
* for suggested.
*/
if (extras->required & ALLEGRO_RENDER_METHOD) {
if (extras->required & (1UL << ALLEGRO_RENDER_METHOD)) {
*a++ = NSOpenGLPFAAccelerated;
}
/*
* OpenGL 3+ support
* Newer versions of macos support modern OpenGL, but won't create a view
* that supports it unless explicitly requested to. Note that even though
* this looks like 3.2 core, it is really >= 3.2, and it is quite strict
* about removing support for legacy OpenGL features, and requires versioned
* shaders.
*/
if (dpy->parent.flags & ALLEGRO_OPENGL_3_0) {
*a++ = NSOpenGLPFAOpenGLProfile;
*a++ = (NSOpenGLPixelFormatAttribute) NSOpenGLProfileVersion3_2Core;
}
}


Expand Down Expand Up @@ -1244,7 +1254,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
[dpy->win setTitle: title];
[dpy->win setAcceptsMouseMovedEvents:YES];
[dpy->win setViewsNeedDisplay:NO];

NSView *window_view = [[NSView alloc] initWithFrame:rect];
[window_view setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
[[dpy->win contentView] addSubview:window_view];
Expand Down Expand Up @@ -1543,7 +1553,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
mask |= NSWindowStyleMaskResizable;
if (display->flags & ALLEGRO_FULLSCREEN)
mask |= NSWindowStyleMaskResizable;

if ((adapter >= 0) &&
(adapter < al_get_num_video_adapters())) {
screen = [[NSScreen screens] objectAtIndex: adapter];
Expand Down Expand Up @@ -1578,7 +1588,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
ALLEGRO_DEBUG("Could not create rendering context\n");
[view release];
[fmt release];

return;
}
/* Hook up the view to its display */
Expand All @@ -1596,15 +1606,15 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
*/
[win setMinSize: NSMakeSize(MINIMUM_WIDTH / screen_scale_factor,
MINIMUM_HEIGHT / screen_scale_factor)];

/* Maximize the window and update its width & height information */
if (display->flags & ALLEGRO_MAXIMIZED) {
[win setFrame: [screen visibleFrame] display: true animate: false];
NSRect content = [win contentRectForFrameRect: [win frame]];
display->w = content.size.width;
display->h = content.size.height;
}

/* Place the window, respecting the location set by the user with
* al_set_new_window_position().
* If the user never called al_set_new_window_position, we simply let
Expand All @@ -1614,7 +1624,7 @@ static void init_new_vsync(ALLEGRO_DISPLAY_OSX_WIN *dpy)
* the range -16000 ... 16000 (approximately, probably the range of a
* signed 16 bit integer). Should we check for this?
*/

if ((x != INT_MAX) && (y != INT_MAX)) {
/* The user gave us window coordinates */
NSRect rc = [win frame];
Expand Down Expand Up @@ -1711,13 +1721,13 @@ static void destroy_display(ALLEGRO_DISPLAY* d)
ALLEGRO_DISPLAY_OSX_WIN* dpy = (ALLEGRO_DISPLAY_OSX_WIN*) d;
ALLEGRO_DISPLAY_OSX_WIN* other = NULL;
unsigned int i;

// Set the display as the current display; needed because we need to
// make the context current.
if (old_dpy != d) {
_al_set_current_display_only(d);
}

/* First of all, save video bitmaps attached to this display. */
// Check for other displays in this display group
_AL_VECTOR* dpys = &al_get_system_driver()->displays;
Expand Down Expand Up @@ -1788,7 +1798,7 @@ static void destroy_display(ALLEGRO_DISPLAY* d)
[dpy->cursor release];
_al_event_source_free(&d->es);
al_free(d->ogl_extras);

// Restore original display from before this function was called.
// If the display we just destroyed is actually current, set the current
// display to NULL.
Expand All @@ -1798,7 +1808,7 @@ static void destroy_display(ALLEGRO_DISPLAY* d)
// Is this redundant? --pw
_al_set_current_display_only(NULL);
}

if (dpy->flip_mutex) {
al_destroy_mutex(dpy->flip_mutex);
al_destroy_cond(dpy->flip_cond);
Expand Down Expand Up @@ -2260,7 +2270,7 @@ static void get_window_position(ALLEGRO_DISPLAY* display, int* px, int* py)
ASSERT_USER_THREAD();
ALLEGRO_DISPLAY_OSX_WIN* d = (ALLEGRO_DISPLAY_OSX_WIN*) display;
NSWindow* window = d->win;

int primary_y = _al_osx_get_primary_screen_y();
float global_scale_factor = _al_osx_get_global_scale_factor();
dispatch_sync(dispatch_get_main_queue(), ^{
Expand Down
15 changes: 15 additions & 0 deletions src/opengl/ogl_shader.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,22 @@ static bool glsl_attach_shader_source(ALLEGRO_SHADER *shader,
if ((*handle) == 0) {
return false;
}
#ifdef ALLEGRO_MACOSX
{
const char *version_string = glGetString(GL_SHADING_LANGUAGE_VERSION);
int version[2];
sscanf(version_string, "%d.%d", &version[0], &version[1]);
char version_line[] = "#version XXXXXXXXXX";
ASSERT(version[0] < 10 && version[1] < 100);
snprintf(version_line, sizeof(version_line), "#version %d%d\n", version[0], version[1]);

const char *sources[] = {version_line, source};

glShaderSource(*handle, 2, sources, NULL);
}
#else
glShaderSource(*handle, 1, &source, NULL);
#endif
glCompileShader(*handle);
glGetShaderiv(*handle, GL_COMPILE_STATUS, &status);
if (status == 0) {
Expand Down
22 changes: 18 additions & 4 deletions src/shader.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,24 +415,38 @@ char const *al_get_default_shader_source(ALLEGRO_SHADER_PLATFORM platform,
ALLEGRO_SHADER_TYPE type)
{
(void)type;
bool use_gl3_shader = false;
#ifdef ALLEGRO_MACOSX
{
ALLEGRO_DISPLAY *display = al_get_current_display();


/* Apple's glsl implementation supports either 1.20 shaders, or strictly
* versioned 3.2+ shaders which do not use deprecated features.
*/
if (display && (display->flags & ALLEGRO_OPENGL_3_0)) {
use_gl3_shader = true;
}
}
#endif
switch (resolve_platform(al_get_current_display(), platform)) {
case ALLEGRO_SHADER_GLSL:
#ifdef ALLEGRO_CFG_SHADER_GLSL
switch (type) {
case ALLEGRO_VERTEX_SHADER:
return default_glsl_vertex_source;
return use_gl3_shader ? default_glsl_vertex_source_gl3 : default_glsl_vertex_source;
case ALLEGRO_PIXEL_SHADER:
return default_glsl_pixel_source;
return use_gl3_shader ? default_glsl_pixel_source_gl3 : default_glsl_pixel_source;
}
#endif
break;
case ALLEGRO_SHADER_GLSL_MINIMAL:
#ifdef ALLEGRO_CFG_SHADER_GLSL
switch (type) {
case ALLEGRO_VERTEX_SHADER:
return default_glsl_vertex_source;
return use_gl3_shader ? default_glsl_vertex_source_gl3 : default_glsl_vertex_source;
case ALLEGRO_PIXEL_SHADER:
return default_glsl_minimal_pixel_source;
return use_gl3_shader ? default_glsl_minimal_pixel_source_gl3 : default_glsl_minimal_pixel_source;
}
#endif
break;
Expand Down
84 changes: 84 additions & 0 deletions src/shader_source.inc
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,90 @@ static const char *default_glsl_minimal_pixel_source =
" gl_FragColor = c;\n"
"}\n";

static const char *default_glsl_vertex_source_gl3 =
"in vec4 " ALLEGRO_SHADER_VAR_POS ";\n"
"in vec4 " ALLEGRO_SHADER_VAR_COLOR ";\n"
"in vec2 " ALLEGRO_SHADER_VAR_TEXCOORD ";\n"
"uniform mat4 " ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX ";\n"
"uniform bool " ALLEGRO_SHADER_VAR_USE_TEX_MATRIX ";\n"
"uniform mat4 " ALLEGRO_SHADER_VAR_TEX_MATRIX ";\n"
"out vec4 varying_color;\n"
"out vec2 varying_texcoord;\n"
"void main()\n"
"{\n"
" varying_color = " ALLEGRO_SHADER_VAR_COLOR ";\n"
" if (" ALLEGRO_SHADER_VAR_USE_TEX_MATRIX ") {\n"
" vec4 uv = " ALLEGRO_SHADER_VAR_TEX_MATRIX " * vec4(" ALLEGRO_SHADER_VAR_TEXCOORD ", 0, 1);\n"
" varying_texcoord = vec2(uv.x, uv.y);\n"
" }\n"
" else\n"
" varying_texcoord = " ALLEGRO_SHADER_VAR_TEXCOORD";\n"
" gl_Position = " ALLEGRO_SHADER_VAR_PROJVIEW_MATRIX " * " ALLEGRO_SHADER_VAR_POS ";\n"
"}\n";

static const char *default_glsl_pixel_source_gl3 =
"#ifdef GL_ES\n"
"precision lowp float;\n"
"#endif\n"
"uniform sampler2D " ALLEGRO_SHADER_VAR_TEX ";\n"
"uniform bool " ALLEGRO_SHADER_VAR_USE_TEX ";\n"
"uniform bool " ALLEGRO_SHADER_VAR_ALPHA_TEST ";\n"
"uniform int " ALLEGRO_SHADER_VAR_ALPHA_FUNCTION ";\n"
"uniform float " ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE ";\n"
"in vec4 varying_color;\n"
"in vec2 varying_texcoord;\n"
"layout(location = 0) out vec4 diffuseColor;\n"
"\n"
"bool alpha_test_func(float x, int op, float compare);\n"
"\n"
"void main()\n"
"{\n"
" vec4 c;\n"
" if (" ALLEGRO_SHADER_VAR_USE_TEX ")\n"
" c = varying_color * texture(" ALLEGRO_SHADER_VAR_TEX ", varying_texcoord);\n"
" else\n"
" c = varying_color;\n"
" if (!" ALLEGRO_SHADER_VAR_ALPHA_TEST " || alpha_test_func(c.a, " ALLEGRO_SHADER_VAR_ALPHA_FUNCTION ", "
ALLEGRO_SHADER_VAR_ALPHA_TEST_VALUE "))\n"
" diffuseColor = c;\n"
" else\n"
" discard;\n"
"}\n"
"\n"
"bool alpha_test_func(float x, int op, float compare)\n"
"{\n"
// Note: These must be aligned with the ALLEGRO_RENDER_FUNCTION enum values.
" if (op == 0) return false;\n" // ALLEGRO_RENDER_NEVER
" else if (op == 1) return true;\n" // ALLEGRO_RENDER_ALWAYS
" else if (op == 2) return x < compare;\n" // ALLEGRO_RENDER_LESS
" else if (op == 3) return x == compare;\n" // ALLEGRO_RENDER_EQUAL
" else if (op == 4) return x <= compare;\n" // ALLEGRO_RENDER_LESS_EQUAL
" else if (op == 5) return x > compare;\n" // ALLEGRO_RENDER_GREATER
" else if (op == 6) return x != compare;\n" // ALLEGRO_RENDER_NOT_EQUAL
" else if (op == 7) return x >= compare;\n" // ALLEGRO_RENDER_GREATER_EQUAL
" return false;\n"
"}\n";

static const char *default_glsl_minimal_pixel_source_gl3 =
"#ifdef GL_ES\n"
"precision lowp float;\n"
"#endif\n"
"uniform sampler2D " ALLEGRO_SHADER_VAR_TEX ";\n"
"uniform bool " ALLEGRO_SHADER_VAR_USE_TEX ";\n"
"in vec4 varying_color;\n"
"in vec2 varying_texcoord;\n"
"layout(location = 0) out vec4 diffuseColor;\n"
"\n"
"void main()\n"
"{\n"
" vec4 c;\n"
" if (" ALLEGRO_SHADER_VAR_USE_TEX ")\n"
" c = varying_color * texture2D(" ALLEGRO_SHADER_VAR_TEX ", varying_texcoord);\n"
" else\n"
" c = varying_color;\n"
" diffuseColor = c;\n"
"}\n";

#endif /* ALLEGRO_CFG_SHADER_GLSL */


Expand Down