Browse Source

OSX support

pull/3386/head
Nikita Tsukanov 7 years ago
parent
commit
db3e2780f1
  1. 3
      samples/ControlCatalog/Pages/OpenGlPage.xaml
  2. 58
      samples/ControlCatalog/Pages/OpenGlPage.xaml.cs
  3. 7
      src/Avalonia.Native/GlPlatformFeature.cs
  4. 3
      src/Avalonia.OpenGL/GlInterfaceBase.cs

3
samples/ControlCatalog/Pages/OpenGlPage.xaml

@ -4,6 +4,9 @@
xmlns:pages="clr-namespace:ControlCatalog.Pages"> xmlns:pages="clr-namespace:ControlCatalog.Pages">
<Grid> <Grid>
<pages:OpenGlPageControl x:Name="GL"/> <pages:OpenGlPageControl x:Name="GL"/>
<StackPanel>
<TextBlock Text="{Binding #GL.Info}"/>
</StackPanel>
<Grid ColumnDefinitions="*,Auto" Margin="20"> <Grid ColumnDefinitions="*,Auto" Margin="20">
<StackPanel Grid.Column="1" MinWidth="300"> <StackPanel Grid.Column="1" MinWidth="300">
<TextBlock>Yaw</TextBlock> <TextBlock>Yaw</TextBlock>

58
samples/ControlCatalog/Pages/OpenGlPage.xaml.cs

@ -66,6 +66,16 @@ namespace ControlCatalog.Pages
set => SetAndRaise(DiscoProperty, ref _disco, value); set => SetAndRaise(DiscoProperty, ref _disco, value);
} }
private string _info;
public static readonly DirectProperty<OpenGlPageControl, string> InfoProperty =
AvaloniaProperty.RegisterDirect<OpenGlPageControl, string>("Info", o => o.Info, (o, v) => o.Info = v);
public string Info
{
get => _info;
private set => SetAndRaise(InfoProperty, ref _info, value);
}
static OpenGlPageControl() static OpenGlPageControl()
{ {
@ -79,13 +89,33 @@ namespace ControlCatalog.Pages
private int _indexBufferObject; private int _indexBufferObject;
private int _vertexArrayObject; private int _vertexArrayObject;
private string WithVersion(string shader) => private string GetShader(bool fragment, string shader)
$"#version {(DisplayType == GlDisplayType.OpenGl ? 120 : 100)}\n" + shader; {
var version = (DisplayType == GlDisplayType.OpenGl ?
RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? 150 : 120 :
100);
var data = "#version " + version + "\n";
if (DisplayType == GlDisplayType.OpenGLES)
data += "precision mediump float\n";
if (version >= 150)
{
shader = shader.Replace("attribute", "in");
if (fragment)
shader = shader
.Replace("varying", "in")
.Replace("//DECLAREGLFRAG", "out vec4 outFragColor;")
.Replace("gl_FragColor", "outFragColor");
else
shader = shader.Replace("varying", "out");
}
data += shader;
return data;
}
private string WithVersionAndPrecision(string shader, string precision) =>
WithVersion(DisplayType == GlDisplayType.OpenGLES ? $"precision {precision};\n{shader}" : shader);
private string VertexShaderSource => WithVersionAndPrecision(@" private string VertexShaderSource => GetShader(false, @"
attribute vec3 aPos; attribute vec3 aPos;
attribute vec3 aNormal; attribute vec3 aNormal;
uniform mat4 uModel; uniform mat4 uModel;
@ -113,9 +143,9 @@ namespace ControlCatalog.Pages
VecPos = aPos; VecPos = aPos;
Normal = normalize(vec3(uModel * vec4(aNormal, 1.0))); Normal = normalize(vec3(uModel * vec4(aNormal, 1.0)));
} }
", "mediump float"); ");
private string FragmentShaderSource => WithVersionAndPrecision(@" private string FragmentShaderSource => GetShader(true, @"
varying vec3 FragPos; varying vec3 FragPos;
varying vec3 VecPos; varying vec3 VecPos;
varying vec3 Normal; varying vec3 Normal;
@ -123,6 +153,7 @@ namespace ControlCatalog.Pages
uniform float uMinY; uniform float uMinY;
uniform float uTime; uniform float uTime;
uniform float uDisco; uniform float uDisco;
//DECLAREGLFRAG
void main() void main()
{ {
@ -154,7 +185,7 @@ namespace ControlCatalog.Pages
gl_FragColor = vec4(result, 1.0); gl_FragColor = vec4(result, 1.0);
} }
", "mediump float"); ");
[StructLayout(LayoutKind.Sequential, Pack = 4)] [StructLayout(LayoutKind.Sequential, Pack = 4)]
private struct Vertex private struct Vertex
@ -224,6 +255,9 @@ namespace ControlCatalog.Pages
protected unsafe override void OnOpenGlInit(GlInterface GL, int fb) protected unsafe override void OnOpenGlInit(GlInterface GL, int fb)
{ {
CheckError(GL); CheckError(GL);
Info = $"Renderer: {GL.GetString(GL_RENDERER)} Version: {GL.GetString(GL_VERSION)}";
// Load the source of the vertex shader and compile it. // Load the source of the vertex shader and compile it.
_vertexShader = GL.CreateShader(GL_VERTEX_SHADER); _vertexShader = GL.CreateShader(GL_VERTEX_SHADER);
Console.WriteLine(GL.CompileShaderAndGetError(_vertexShader, VertexShaderSource)); Console.WriteLine(GL.CompileShaderAndGetError(_vertexShader, VertexShaderSource));
@ -247,6 +281,7 @@ namespace ControlCatalog.Pages
_vertexBufferObject = GL.GenBuffer(); _vertexBufferObject = GL.GenBuffer();
// Bind the VBO and copy the vertex data into it. // Bind the VBO and copy the vertex data into it.
GL.BindBuffer(GL_ARRAY_BUFFER, _vertexBufferObject); GL.BindBuffer(GL_ARRAY_BUFFER, _vertexBufferObject);
CheckError(GL);
var vertexSize = Marshal.SizeOf<Vertex>(); var vertexSize = Marshal.SizeOf<Vertex>();
fixed (void* pdata = _points) fixed (void* pdata = _points)
GL.BufferData(GL_ARRAY_BUFFER, new IntPtr(_points.Length * vertexSize), GL.BufferData(GL_ARRAY_BUFFER, new IntPtr(_points.Length * vertexSize),
@ -254,13 +289,14 @@ namespace ControlCatalog.Pages
_indexBufferObject = GL.GenBuffer(); _indexBufferObject = GL.GenBuffer();
GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject); GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject);
CheckError(GL);
fixed (void* pdata = _indices) fixed (void* pdata = _indices)
GL.BufferData(GL_ELEMENT_ARRAY_BUFFER, new IntPtr(_indices.Length * sizeof(ushort)), new IntPtr(pdata), GL.BufferData(GL_ELEMENT_ARRAY_BUFFER, new IntPtr(_indices.Length * sizeof(ushort)), new IntPtr(pdata),
GL_STATIC_DRAW); GL_STATIC_DRAW);
CheckError(GL);
_vertexArrayObject = GL.GenVertexArray(); _vertexArrayObject = GL.GenVertexArray();
GL.BindVertexArray(_vertexArrayObject); GL.BindVertexArray(_vertexArrayObject);
CheckError(GL);
GL.VertexAttribPointer(positionLocation, 3, GL_FLOAT, GL.VertexAttribPointer(positionLocation, 3, GL_FLOAT,
0, vertexSize, IntPtr.Zero); 0, vertexSize, IntPtr.Zero);
GL.VertexAttribPointer(normalLocation, 3, GL_FLOAT, GL.VertexAttribPointer(normalLocation, 3, GL_FLOAT,
@ -300,6 +336,7 @@ namespace ControlCatalog.Pages
GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject); GL.BindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferObject);
GL.BindVertexArray(_vertexArrayObject); GL.BindVertexArray(_vertexArrayObject);
GL.UseProgram(_shaderProgram); GL.UseProgram(_shaderProgram);
CheckError(GL);
var projection = var projection =
Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)(Bounds.Width / Bounds.Height), Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.PI / 4), (float)(Bounds.Width / Bounds.Height),
0.01f, 1000); 0.01f, 1000);
@ -321,6 +358,7 @@ namespace ControlCatalog.Pages
GL.Uniform1f(minYLoc, _minY); GL.Uniform1f(minYLoc, _minY);
GL.Uniform1f(timeLoc, (float)St.Elapsed.TotalSeconds); GL.Uniform1f(timeLoc, (float)St.Elapsed.TotalSeconds);
GL.Uniform1f(discoLoc, _disco); GL.Uniform1f(discoLoc, _disco);
CheckError(GL);
GL.DrawElements(GL_TRIANGLES, _indices.Length, GL_UNSIGNED_SHORT, IntPtr.Zero); GL.DrawElements(GL_TRIANGLES, _indices.Length, GL_UNSIGNED_SHORT, IntPtr.Zero);
CheckError(GL); CheckError(GL);

7
src/Avalonia.Native/GlPlatformFeature.cs

@ -8,8 +8,11 @@ namespace Avalonia.Native
{ {
class GlPlatformFeature : IWindowingPlatformGlFeature class GlPlatformFeature : IWindowingPlatformGlFeature
{ {
private readonly IAvnGlDisplay _display;
public GlPlatformFeature(IAvnGlDisplay display) public GlPlatformFeature(IAvnGlDisplay display)
{ {
_display = display;
var immediate = display.CreateContext(null); var immediate = display.CreateContext(null);
var deferred = display.CreateContext(immediate); var deferred = display.CreateContext(immediate);
GlDisplay = new GlDisplay(display, immediate.SampleCount, immediate.StencilSize); GlDisplay = new GlDisplay(display, immediate.SampleCount, immediate.StencilSize);
@ -22,7 +25,9 @@ namespace Avalonia.Native
internal GlContext DeferredContext { get; } internal GlContext DeferredContext { get; }
internal GlDisplay GlDisplay; internal GlDisplay GlDisplay;
public IGlDisplay Display => GlDisplay; public IGlDisplay Display => GlDisplay;
public IGlContext CreateContext() => new GlContext(GlDisplay, ((GlContext)ImmediateContext).Context);
public IGlContext CreateContext() => new GlContext(GlDisplay,
_display.CreateContext(((GlContext)ImmediateContext).Context));
} }
class GlDisplay : IGlDisplay class GlDisplay : IGlDisplay

3
src/Avalonia.OpenGL/GlInterfaceBase.cs

@ -30,7 +30,8 @@ namespace Avalonia.OpenGL
foreach (var ep in a.EntryPoints) foreach (var ep in a.EntryPoints)
{ {
proc = getProcAddress(ep, true); proc = getProcAddress(ep, true);
if(proc != IntPtr.Zero)
break;
} }
if (proc == IntPtr.Zero && !a.Optional) if (proc == IntPtr.Zero && !a.Optional)

Loading…
Cancel
Save