惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
腾讯CDC
宝玉的分享
宝玉的分享
量子位
Recent Announcements
Recent Announcements
Martin Fowler
Martin Fowler
J
Java Code Geeks
V
Visual Studio Blog
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
S
SegmentFault 最新的问题
B
Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
小众软件
小众软件
The Cloudflare Blog
Y
Y Combinator Blog
I
InfoQ
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
GbyAI
GbyAI
IT之家
IT之家

博客园 - dalgleish

C# Avalonia 23- OpenGL- HitTestTorus Helix C++引擎公测 - 使用ImGUI C# Avalonia 23- OpenGL- VideoIn3D C# Avalonia 23- OpenGL- Materials Helix C++引擎公测 C# Avalonia 23- OpenGL- CubeMesh Helix C++ 跨平台内存安全扩展 C# Avalonia 23- OpenGL- BasicOpenGL C# Avalonia 23- OpenGL- 例子通用类 C# Avalonia 22- SoundAndVideo- SpeechVoiceTest C# Avalonia 22- SoundAndVideo- SpeechRecognition C# Avalonia 22- SoundAndVideo- SpeechSynthesis C# Avalonia 22- SoundAndVideo- CodePlayback C# Avalonia 22- SoundAndVideo- SoundPlayerTest C# Avalonia 21- MenusAndToolbars- RibbonTest C# Avalonia 21- MenusAndToolbars- ProportionalStatusBar C# Avalonia 21- MenusAndToolbars- BasicToolbar C# Avalonia 21- MenusAndToolbars- ToolBar/Ribbon开源项目介绍和修复 C# Avalonia 21- MenusAndToolbars- SidebarMenu C# Avalonia 21- MenusAndToolbars- MixedMenus C# Avalonia 20 - WindowsMenu- 魔改Hyperlink - 使用例子 C# Avalonia 20 - WindowsMenu- 魔改Hyperlink C# Avalonia 20 - WindowsMenu- WebViewTest C# Avalonia 20 - WindowsMenu- WebView C# Avalonia 20 - WindowsMenu- ModernWindowTest C# Avalonia 20 - WindowsMenu- ModernWindow C# Avalonia 20 - WindowsMenu- TransparentWithShapes C# Avalonia 20 - WindowsMenu- TransparentBackground C# Avalonia 20 - WindowsMenu- OpenFileTest C# Avalonia 20 - WindowsMenu- SavePostion
C# Avalonia 23- OpenGL- TriangleGlView
dalgleish · 2026-08-10 · via 博客园 - dalgleish

TriangleGlView.axaml代码

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Height="300" Width="300"
         xmlns:local="using:AvaloniaUI"
        x:Class="AvaloniaUI.OneTriangleMesh"
        Title="OneTriangleMesh">
    <Grid Margin="5">
        <Border BorderBrush="Yellow" BorderThickness="1">
            <local:TriangleGlView/>
        </Border>
    </Grid>
</Window>

TriangleGlView.axaml.cs代码

using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Controls;
using Avalonia.Rendering;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System;
using System.Diagnostics;
using System.Numerics;

namespace AvaloniaUI;

public sealed class TriangleGlView : OpenGlControlBase
{
    private int program;
    private int vao;
    private int vbo;

    protected override void OnOpenGlInit(GlInterface gl)
    {
        GL.LoadBindings(new BindingsContext(gl));

        GL.Disable(EnableCap.DepthTest);

        CreateTriangle();
        CreateProgram();

        //这个版本和version 300 es对应
        var version = GL.GetString(StringName.Version);
        var sl = GL.GetString(StringName.ShadingLanguageVersion);
        var renderer = GL.GetString(StringName.Renderer);
        var vendor = GL.GetString(StringName.Vendor);

        Console.WriteLine($"GL_VERSION: {version}");
        Console.WriteLine($"GLSL: {sl}");
        Console.WriteLine($"Renderer: {renderer}");
        Console.WriteLine($"Vendor: {vendor}");
    }

    protected override void OnOpenGlDeinit(GlInterface gl)
    {
        if (program != 0) GL.DeleteProgram(program);
        if (vbo != 0) GL.DeleteBuffer(vbo);
        if (vao != 0) GL.DeleteVertexArray(vao);

        program = 0;
        vbo = 0;
        vao = 0;
    }

    protected override void OnOpenGlRender(GlInterface gl, int fb)
    {
        //RequestNextFrameRendering();

        var width = Math.Max(1, (int)Bounds.Width);
        var height = Math.Max(1, (int)Bounds.Height);

        GL.Viewport(0, 0, width, height);

        GL.ClearColor(0.5f, 0.5f, 0.5f, 1f);
        GL.Clear(ClearBufferMask.ColorBufferBit);

        GL.UseProgram(program);
        GL.BindVertexArray(vao);
        GL.DrawArrays(PrimitiveType.Triangles, 0, 3);
    }

    private void CreateTriangle()
    {
        var vertices = new[]
        {
            -0.8f, -0.6f, 0f,
             0.0f,  0.8f, 0f,
             0.8f, -0.6f, 0f
        };

        vao = GL.GenVertexArray();
        vbo = GL.GenBuffer();

        GL.BindVertexArray(vao);
        GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
        GL.BufferData(BufferTarget.ArrayBuffer, vertices.Length * sizeof(float), vertices, BufferUsageHint.StaticDraw);

        GL.EnableVertexAttribArray(0);
        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 3 * sizeof(float), 0);
    }

    private void CreateProgram()
    {
        var vsSource = """
              #version 300 es
              layout(location=0) in vec3 aPos;
              void main()
              {
                  gl_Position = vec4(aPos, 1.0);
              }
              """;

        var fsSource =  """
              #version 300 es
              precision mediump float;
              out vec4 FragColor;
              void main()
              {
                  FragColor = vec4(1.0, 1.0, 0.0, 1.0);
              }
              """;

        var vs = CompileShader(ShaderType.VertexShader, vsSource);
        var fs = CompileShader(ShaderType.FragmentShader, fsSource);

        program = GL.CreateProgram();
        GL.AttachShader(program, vs);
        GL.AttachShader(program, fs);
        GL.LinkProgram(program);

        GL.GetProgram(program, GetProgramParameterName.LinkStatus, out var linked);
        if (linked == 0)
        {
            var log = GL.GetProgramInfoLog(program);
            GL.DeleteProgram(program);
            program = 0;
            throw new InvalidOperationException($"Link failed: {log}");
        }

        GL.DetachShader(program, vs);
        GL.DetachShader(program, fs);
        GL.DeleteShader(vs);
        GL.DeleteShader(fs);
    }

    private static int CompileShader(ShaderType type, string source)
    {
        var shader = GL.CreateShader(type);
        GL.ShaderSource(shader, source);
        GL.CompileShader(shader);

        GL.GetShader(shader, ShaderParameter.CompileStatus, out var ok);
        if (ok == 0)
        {
            var log = GL.GetShaderInfoLog(shader);
            GL.DeleteShader(shader);
            throw new InvalidOperationException($"{type} compile failed: {log}");
        }

        return shader;
    }

    private sealed class BindingsContext(GlInterface gl) : IBindingsContext
    {
        public IntPtr GetProcAddress(string procName) => gl.GetProcAddress(procName);
    }
}
public partial class OneTriangleMesh : Window
{
    public OneTriangleMesh()
    {
        InitializeComponent();
    }
}

运行效果

image