zoukankan      html  css  js  c++  java
  • 使用Visual Studio SDK制作GLSL词法着色插件

    本文转自(http://www.cnblogs.com/aanbpsd/p/3920067.html

    原作者故意写错了一点东西,这就让那些一点脑筋也不想动的小伙伴得不到想要的结果。我在这里把那些地方纠正过来了。

    使用Visual Studio SDK制作GLSL词法着色插件

    我们在Visual Studio上开发OpenGL ES项目时,避免不了写Shader。这时在vs里直接编辑shader就会显得很方便。但是vs默认是不支持GLSL的语法着色的,我们只好自己动手创造。最简单的实现自定义语法着色的方法就是创建一个VSIX插件包,我们只需要安装Visual Studio SDK,使用内置的模版就可以构建一个插件项目

    1. 安装Visual Studio SDK


    http://www.microsoft.com/en-us/download/details.aspx?id=40758下载最新的Visual Studio 2013 SDK。

    双击安装,一路next即可。

    安装完毕后我们可以在新建项目->模版->C#中看到“扩展性”这一条目,这些就是开发插件用的模版了。

    2. 创建插件项目


    新建项目,在扩展性标签中,选择Editor Classifier模版,命名为ShaderEditor,点击确定。

    Visual Studio为我们生成了如下几个文件。

    ShaderEditorFormat.cs文件的默认代码如下: 

    复制代码
     1     [Export(typeof(EditorFormatDefinition))]
     2     [ClassificationType(ClassificationTypeNames = "ShaderEditor")]
     3     [Name("ShaderEditor")]
     4     [UserVisible(true)] //this should be visible to the end user
     5     [Order(Before = Priority.Default)] //set the priority to be after the default classifiers
     6     internal sealed class ShaderEditorFormat : ClassificationFormatDefinition {
     7         /// <summary>
     8         /// Defines the visual format for the "ShaderEditor" classification type
     9         /// </summary>
    10         public ShaderEditorFormat() {
    11             this.DisplayName = "ShaderEditor"; //human readable version of the name
    12             this.BackgroundColor = Colors.BlueViolet;
    13             this.TextDecorations = System.Windows.TextDecorations.Underline;
    14         }
    15     }
    复制代码

    这段代码定义了一个名为"ShaderEditor"的着色类型,编译工程并运行,我们可以在Visual Studio实验实例的工具->选项->字体和颜色中找到一个名为"ShaderEditor"的条目。同时我们会发现所有文本文件的颜色都变成了Colors.BlueViolet并带上了下划线。修改this.DisplayName = "ShaderEditor"的内容,可以改变在字体和颜色中显示的名字。下面的格式设置可以任意修改成喜欢的样式,但要注意在这里的格式只是插件首次安装时的默认设置,这些条目和其它着色选项一样,都可以被用户任意更改。

    3. 创建GLSL的着色类型

    
    

    我们已经了解了如何将着色类型添加到Visual Studio,现在修改ShaderEditorFormat.cs,添加我们的着色类型。

      1     #region Format definition
      2     [Export(typeof(EditorFormatDefinition))]
      3     [ClassificationType(ClassificationTypeNames = "GLSLText")]
      4     [Name("GLSLText")]
      5     [UserVisible(true)]
      6     [Order(Before = Priority.Default)]
      7     internal sealed class GLSLTextFormatDefinition : ClassificationFormatDefinition
      8     {
      9         public GLSLTextFormatDefinition()
     10         {
     11             this.DisplayName = "GLSL文本";
     12             this.ForegroundColor = Colors.Brown;
     13         }
     14     }
     15 
     16     [Export(typeof(EditorFormatDefinition))]
     17     [ClassificationType(ClassificationTypeNames = "GLSLIdentifier")]
     18     [Name("GLSLIdentifier")]
     19     [UserVisible(true)]
     20     [Order(Before = Priority.Default)]
     21     internal sealed class GLSLIdentifierFormatDefinition : ClassificationFormatDefinition
     22     {
     23         public GLSLIdentifierFormatDefinition()
     24         {
     25             this.DisplayName = "GLSL标识符";
     26             this.ForegroundColor = Colors.Brown;
     27         }
     28     }
     29 
     30     [Export(typeof(EditorFormatDefinition))]
     31     [ClassificationType(ClassificationTypeNames = "GLSLComment")]
     32     [Name("GLSLComment")]
     33     [UserVisible(true)]
     34     [Order(Before = Priority.Default)]
     35     internal sealed class GLSLCommentFormatDefinition : ClassificationFormatDefinition
     36     {
     37         public GLSLCommentFormatDefinition()
     38         {
     39             this.DisplayName = "GLSL注释";
     40             this.ForegroundColor = Colors.DarkGray;
     41         }
     42     }
     43 
     44     [Export(typeof(EditorFormatDefinition))]
     45     [ClassificationType(ClassificationTypeNames = "GLSLKeyword")]
     46     [Name("GLSLKeyword")]
     47     [UserVisible(true)]
     48     [Order(Before = Priority.Default)]
     49     internal sealed class GLSLKeywordFormatDefinition : ClassificationFormatDefinition
     50     {
     51         public GLSLKeywordFormatDefinition()
     52         {
     53             this.DisplayName = "GLSL关键字";
     54             this.ForegroundColor = Colors.Blue;
     55         }
     56     }
     57 
     58     [Export(typeof(EditorFormatDefinition))]
     59     [ClassificationType(ClassificationTypeNames = "GLSLClass")]
     60     [Name("GLSLClass")]
     61     [UserVisible(true)]
     62     [Order(Before = Priority.Default)]
     63     internal sealed class GLSLClassFormatDefinition : ClassificationFormatDefinition
     64     {
     65         public GLSLClassFormatDefinition()
     66         {
     67             this.DisplayName = "GLSL类型";
     68             this.ForegroundColor = Colors.Green;
     69         }
     70     }
     71 
     72     [Export(typeof(EditorFormatDefinition))]
     73     [ClassificationType(ClassificationTypeNames = "GLSLQualifier")]
     74     [Name("GLSLQualifier")]
     75     [UserVisible(true)]
     76     [Order(Before = Priority.Default)]
     77     internal sealed class GLSLQualifierFormatDefinition : ClassificationFormatDefinition
     78     {
     79         public GLSLQualifierFormatDefinition()
     80         {
     81             this.DisplayName = "GLSL限定符";
     82             this.ForegroundColor = Colors.Pink;
     83         }
     84     }
     85 
     86     [Export(typeof(EditorFormatDefinition))]
     87     [ClassificationType(ClassificationTypeNames = "GLSLVariable")]
     88     [Name("GLSLVariable")]
     89     [UserVisible(true)]
     90     [Order(Before = Priority.Default)]
     91     internal sealed class GLSLVariableFormatDefinition : ClassificationFormatDefinition
     92     {
     93         public GLSLVariableFormatDefinition()
     94         {
     95             this.DisplayName = "GLSL系统变量";
     96             this.ForegroundColor = Colors.DarkOrange;
     97         }
     98     }
     99 
    100     [Export(typeof(EditorFormatDefinition))]
    101     [ClassificationType(ClassificationTypeNames = "GLSLFunction")]
    102     [Name("GLSLFunction")]
    103     [UserVisible(true)]
    104     [Order(Before = Priority.Default)]
    105     internal sealed class GLSLFunctionFormatDefinition : ClassificationFormatDefinition
    106     {
    107         public GLSLFunctionFormatDefinition()
    108         {
    109             this.DisplayName = "GLSL系统函数";
    110             this.ForegroundColor = Colors.DarkTurquoise;
    111         }
    112     }
    113     #endregion //Format definition

    4. 导出着色类型


    Editor Classifier使用了MEF框架,关于MEF的具体细节,请参考MSDN的相关文档。

    我们需要注意的是,在MEF中,光定义了着色类型还不够,我们需要导出一个ClassificationTypeDefinition,才能在系统中生效。

    打开ShaderEditorType.cs,我们看到系统生成的代码如下:

    1     internal static class ShaderEditorClassificationDefinition {
    2         [Export(typeof(ClassificationTypeDefinition))]
    3         [Name("ShaderEditor")]
    4         internal static ClassificationTypeDefinition ShaderEditorType = null;
    5     }

    这里的Name与之前默认生成的ShaderEditor相同,同理,我们将这里的代码修改成方才定义的类型

     1     internal static class ShaderEditorClassificationDefinition
     2     {
     3         [Export(typeof(ClassificationTypeDefinition))]
     4         [Name("GLSLText")]
     5         internal static ClassificationTypeDefinition GLSLTextType = null;
     6 
     7         [Export(typeof(ClassificationTypeDefinition))]
     8         [Name("GLSLIdentifier")]
     9         internal static ClassificationTypeDefinition GLSLIdentifierType = null;
    10 
    11         [Export(typeof(ClassificationTypeDefinition))]
    12         [Name("GLSLComment")]
    13         internal static ClassificationTypeDefinition GLSLCommentType = null;
    14 
    15         [Export(typeof(ClassificationTypeDefinition))]
    16         [Name("GLSLKeyword")]
    17         internal static ClassificationTypeDefinition GLSLKeywordType = null;
    18 
    19         [Export(typeof(ClassificationTypeDefinition))]
    20         [Name("GLSLClass")]
    21         internal static ClassificationTypeDefinition GLSLClassType = null;
    22 
    23         [Export(typeof(ClassificationTypeDefinition))]
    24         [Name("GLSLQualifier")]
    25         internal static ClassificationTypeDefinition GLSLQualifierType = null;
    26 
    27         [Export(typeof(ClassificationTypeDefinition))]
    28         [Name("GLSLVariable")]
    29         internal static ClassificationTypeDefinition GLSLVariableType = null;
    30 
    31         [Export(typeof(ClassificationTypeDefinition))]
    32         [Name("GLSLFunction")]
    33         internal static ClassificationTypeDefinition GLSLFunctionType = null;
    34     }

    5. 关联文件类型


    打开ShaderEditor.cs

    复制代码
     1     [Export(typeof(IClassifierProvider))]
     2     [ContentType("text")]
     3     internal class ShaderEditorProvider : IClassifierProvider {
     4         [Import]
     5         internal IClassificationTypeRegistryService ClassificationRegistry = null; // Set via MEF
     6 
     7         public IClassifier GetClassifier(ITextBuffer buffer) {
     8             return buffer.Properties.GetOrCreateSingletonProperty<ShaderEditor>(delegate { return new ShaderEditor(ClassificationRegistry); });
     9         }
    10     }
    复制代码

    代码ContentType("text")创建了一个Provider并将它们对所有text类型的文件生效。

    GLSL主要的文件扩展名为.vsh和.fsh,为了只对这两个扩展名生效,我们需要自定义一个ContentType,并创建两个扩展名关联。将上述代码修改为:

     1     [Export(typeof(ITaggerProvider))]
     2     [ContentType("glsl")]
     3     [TagType(typeof(ClassificationTag))]
     4     internal sealed class GLSLClassifierProvider : ITaggerProvider {
     5 
     6         [Export]
     7         [Name("glsl")]
     8         [BaseDefinition("code")]
     9         internal static ContentTypeDefinition GLSLContentType = null;
    10 
    11         [Export]
    12         [FileExtension(".vsh")]
    13         [ContentType("glsl")]
    14         internal static FileExtensionToContentTypeDefinition GLSLVshType = null;
    15 
    16         [Export]
    17         [FileExtension(".fsh")]
    18         [ContentType("glsl")]
    19         internal static FileExtensionToContentTypeDefinition GLSLFshType = null;
    20 
    21         [Import]
    22         internal IClassificationTypeRegistryService classificationTypeRegistry = null;
    23 
    24         [Import]
    25         internal IBufferTagAggregatorFactoryService aggregatorFactory = null;
    26 
    27         public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag {
    28             return new GLSLClassifier(buffer, classificationTypeRegistry) as ITagger<T>;
    29         }
    30     }

    (这段代码有问题,请用我改过的)

     1     [Export(typeof(ITaggerProvider))]
     2     [ContentType("glsl")]
     3     [TagType(typeof(ClassificationTag))]
     4     internal sealed class GLSLClassifierProvider : ITaggerProvider
     5     {
     6 
     7         [Export]
     8         [Name("glsl")]
     9         [BaseDefinition("code")]
    10         internal static ContentTypeDefinition GLSLContentType = null;
    11 
    12         [Export]
    13         [FileExtension(".vert")]
    14         [ContentType("glsl")]
    15         internal static FileExtensionToContentTypeDefinition GLSLVshType = null;
    16 
    17         [Export]
    18         [FileExtension(".frag")]
    19         [ContentType("glsl")]
    20         internal static FileExtensionToContentTypeDefinition GLSLFshType = null;
    21 
    22         [Export]
    23         [FileExtension(".geom")]
    24         [ContentType("glsl")]
    25         internal static FileExtensionToContentTypeDefinition GLSLGshType = null;
    26 
    27         [Import]
    28         internal IClassificationTypeRegistryService classificationTypeRegistry = null;
    29 
    30         [Import]
    31         internal IBufferTagAggregatorFactoryService aggregatorFactory = null;
    32 
    33         public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
    34         {
    35             return new GLSLClassifier(buffer, classificationTypeRegistry) as ITagger<T>;
    36         }
    37     }

    这样我们就创建了只针对vert、frag和geom文件生效的Editor。也就是顶点Shader、片段Shader和几何Shader。

    6. 使用gplex进行词法分析


    我们需要使用词法分析扫描器来实现具体的着色功能,gplex可以为我们生成C#语言的扫描器,下载地址:

    http://gplex.codeplex.com/

    解压后在binaries文件夹下找到gplex.exe,把它拷贝到项目的根目录下。

    在项目根目录下新建一个GLSL文件夹,新建GLSLLexer.lex文件。并把它们添加到proj中。

    在proj上右键->属性,在生成事件选项卡中,在预先生成事件命令行中输入

    cd $(ProjectDir)GLSL
    $(ProjectDir)gplex GLSLLexer

    打开GLSLLexer.lex,写入以下代码:

    复制代码
     1 %option unicode, codepage:raw
     2 
     3 %{
     4         // User code is all now in ScanHelper.cs
     5 %}
     6 
     7 %namespace Shane
     8 %option verbose, summary, noparser, nofiles, unicode
     9 
    10 %{
    11     public int nextToken() { return yylex(); }
    12     public int getPos() { return yypos; }
    13     public int getLength() { return yyleng; }
    14 %}
    15 
    16 //=============================================================
    17 //=============================================================
    18 
    19 number ([0-9])+
    20 chars [A-Za-z]
    21 cstring [A-Za-z_]
    22 blank " "
    23 delim [ 	
    ]
    24 word {chars}+
    25 singleLineComment "//"[^
    ]*
    26 multiLineComment "/*"[^*]**(*|([^*/]([^*])**))*/
    27 
    28 comment {multiLineComment}|{singleLineComment}
    29 class bool|int|float|bvec|ivec|vec|vec2|vec3|vec4|mat2|mat3|mat4|sampler1D|sampler2D|sampler3D|samplerCube|sampler1DShadow|sampler2DShadow
    30 keyword return|if|else|while|do|for|foreach|break|continue|switch|case|default|goto|class|struct|enum|extern|interface|namespace|public|static|this|volatile|using|in|out|true|false
    31 qualifier const|attribute|uniform|varying
    32 systemVariable gl_BackColor|gl_BackLightModelProduct|gl_BackLightProduct|gl_BackMaterial|gl_BackSecondaryColor|gl_ClipPlane|gl_ClipVertex|gl_Color|gl_DepthRange|gl_DepthRangeParameters|gl_EyePlaneQ|gl_EyePlaneR|gl_EyePlaneS|gl_EyePlaneT|gl_Fog|gl_FogCoord|gl_FogFragCoord|gl_FogParameters|gl_FragColor|gl_FragCoord|gl_FragData|gl_FragDepth|gl_FrontColor|gl_FrontFacing|gl_FrontLightModelProduct|gl_FrontLightProduct|gl_FrontMaterial|gl_FrontSecondaryColor|gl_LightModel|gl_LightModelParameters|gl_LightModelProducts|gl_LightProducts|gl_LightSource|gl_LightSourceParameters|gl_MaterialParameters|gl_MaxClipPlanes|gl_MaxCombinedTextureImageUnits|gl_MaxDrawBuffers|gl_MaxFragmentUniformComponents|gl_MaxLights|gl_MaxTextureCoords|gl_MaxTextureImageUnits|gl_MaxTextureUnits|gl_MaxVaryingFloats|gl_MaxVertexAttribs|gl_MaxVertexTextureImageUnits|gl_MaxVertexUniformComponents|gl_ModelViewMatrix|gl_ModelViewMatrixInverse|gl_ModelViewMatrixInverseTranspose|gl_ModelViewMatrixTranspose|gl_ModelViewProjectionMatrix|gl_ModelViewProjectionMatrixInverse|gl_ModelViewProjectionMatrixInverseTranspose|gl_ModelViewProjectionMatrixTranspose|gl_MultiTexCoord0|gl_MultiTexCoord1|gl_MultiTexCoord10|gl_MultiTexCoord11|gl_MultiTexCoord2|gl_MultiTexCoord3|gl_MultiTexCoord4|gl_MultiTexCoord5|gl_MultiTexCoord6|gl_MultiTexCoord7|gl_MultiTexCoord8|gl_MultiTexCoord9|gl_Normal|gl_NormalMatrix|gl_NormalScale|gl_ObjectPlaneQ|gl_ObjectPlaneR|gl_ObjectPlaneS|gl_ObjectPlaneT|gl_Point|gl_PointParameters|gl_PointSize|gl_Position|gl_ProjectionMatrix|gl_ProjectionMatrixInverse|gl_ProjectionMatrixInverseTranspose|gl_ProjectionMatrixTranspose|gl_SecondaryColor|gl_TexCoord|gl_TextureEnvColor|gl_TextureMatrix|gl_TextureMatrixInverse|gl_TextureMatrixInverseTranspose|gl_TextureMatrixTranspose|gl_Vertex
    33 systemFunction radians|degress|sin|cos|tan|asin|acos|atan|pow|exp|log|exp2|log2|sqrt|inversesqrt|abs|sign|floor|ceil|fract|mod|min|max|clamp|mix|step|smoothstep|length|distance|dot|cross|normalize|faceforward|reflect|matrixCompMult|lessThan|lessThanEqual|greaterThan|greaterThanEqual|equal|notEqual|any|all|not|texture2D|texture2DProj|texture2DLod|texture2DProjLod|textureCube|textureCubeLod
    34 identifier {cstring}+{number}*[{cstring}@]*{number}*
    35 
    36 %%
    37 
    38 {keyword}            return (int)GLSLTokenType.Keyword;
    39 {class}                return (int)GLSLTokenType.Class;
    40 {qualifier}            return (int)GLSLTokenType.Qualifier;
    41 {systemVariable}    return (int)GLSLTokenType.SystemVariable;
    42 {systemFunction}    return (int)GLSLTokenType.SystemFunction;
    43 {identifier}        return (int)GLSLTokenType.Identifier;
    44 {comment}            return (int)GLSLTokenType.Comment;
    45 
    46 %%
    复制代码

    保存并关闭,这时生成一下项目,我们会看到在GLSL目录下生成了GLSLLexer.cs文件,同样把这个文件添加到proj中。

    如果你很懒,可以直接用这个(点此下载),这是我已经生成了的GLSLLexer.cs。(源码太大,多次上传失败)

    7. 处理扫描结果 


    接下来我们要在ShaderEditor.cs中处理我们的扫描结果,并最终对匹配的代码行进行着色。

    首先删除默认创建的ShaderEditor类。

    添加一个GLSLToken枚举,这个枚举就是GLSLLexer.cs返回的枚举类型,它用来通知我们当前的语句块是哪个类型。

    代码如下:

     1     public enum GLSLTokenType
     2     {
     3         Text = 1,
     4         Keyword,
     5         Comment,
     6         Identifier,
     7         Class,
     8         Qualifier,
     9         SystemVariable,
    10         SystemFunction
    11     }

    创建我们自己的ShaderEditor类,代码如下:

      1     #region Provider definition
      2     [Export(typeof(ITaggerProvider))]
      3     [ContentType("glsl")]
      4     [TagType(typeof(ClassificationTag))]
      5     internal sealed class GLSLClassifierProvider : ITaggerProvider
      6     {
      7 
      8         [Export]
      9         [Name("glsl")]
     10         [BaseDefinition("code")]
     11         internal static ContentTypeDefinition GLSLContentType = null;
     12 
     13         [Export]
     14         [FileExtension(".vert")]
     15         [ContentType("glsl")]
     16         internal static FileExtensionToContentTypeDefinition GLSLVshType = null;
     17 
     18         [Export]
     19         [FileExtension(".frag")]
     20         [ContentType("glsl")]
     21         internal static FileExtensionToContentTypeDefinition GLSLFshType = null;
     22 
     23         [Export]
     24         [FileExtension(".geom")]
     25         [ContentType("glsl")]
     26         internal static FileExtensionToContentTypeDefinition GLSLGshType = null;
     27 
     28         [Import]
     29         internal IClassificationTypeRegistryService classificationTypeRegistry = null;
     30 
     31         [Import]
     32         internal IBufferTagAggregatorFactoryService aggregatorFactory = null;
     33 
     34         public ITagger<T> CreateTagger<T>(ITextBuffer buffer) where T : ITag
     35         {
     36             return new GLSLClassifier(buffer, classificationTypeRegistry) as ITagger<T>;
     37         }
     38     }
     39     #endregion //provider def
     40 
     41     #region Classifier
     42     internal sealed class GLSLClassifier : ITagger<ClassificationTag>
     43     {
     44         internal GLSLClassifier(ITextBuffer buffer, IClassificationTypeRegistryService typeService)
     45         {
     46             textBuffer = buffer;
     47             typeDic = new Dictionary<GLSLTokenType, IClassificationType>();
     48             typeDic[GLSLTokenType.Text] = typeService.GetClassificationType("GLSLText");
     49             typeDic[GLSLTokenType.Identifier] = typeService.GetClassificationType("GLSLIdentifier");
     50             typeDic[GLSLTokenType.Keyword] = typeService.GetClassificationType("GLSLKeyword");
     51             typeDic[GLSLTokenType.Class] = typeService.GetClassificationType("GLSLClass");
     52             typeDic[GLSLTokenType.Comment] = typeService.GetClassificationType("GLSLComment");
     53             typeDic[GLSLTokenType.Qualifier] = typeService.GetClassificationType("GLSLQualifier");
     54             typeDic[GLSLTokenType.SystemVariable] = typeService.GetClassificationType("GLSLVariable");
     55             typeDic[GLSLTokenType.SystemFunction] = typeService.GetClassificationType("GLSLFunction");
     56         }
     57 
     58         public event EventHandler<SnapshotSpanEventArgs> TagsChanged
     59         {
     60             add { }
     61             remove { }
     62         }
     63 
     64         public IEnumerable<ITagSpan<ClassificationTag>> GetTags(NormalizedSnapshotSpanCollection spans)
     65         {
     66             IClassificationType classification = typeDic[GLSLTokenType.Text];
     67             string text = spans[0].Snapshot.GetText();
     68             yield return new TagSpan<ClassificationTag>(
     69                 new SnapshotSpan(spans[0].Snapshot, new Span(0, text.Length)),
     70                 new ClassificationTag(classification));
     71             scanner.SetSource(text, 0);
     72             int tok;
     73             do
     74             {
     75                 tok = scanner.nextToken();
     76                 int pos = scanner.getPos();
     77                 int len = scanner.getLength();
     78                 int total = text.Length;
     79                 if (pos < 0 || len < 0 || pos > total)
     80                 {
     81                     continue;
     82                 }
     83                 if (pos + len > total)
     84                 {
     85                     len = total - pos;
     86                 }
     87                 if (typeDic.TryGetValue((GLSLTokenType)tok, out classification))
     88                 {
     89                     yield return new TagSpan<ClassificationTag>(
     90                         new SnapshotSpan(spans[0].Snapshot, new Span(pos, len)),
     91                         new ClassificationTag(classification));
     92                 }
     93             } while (tok > (int)Tokens.EOF);
     94         }
     95 
     96         ITextBuffer textBuffer;
     97         IDictionary<GLSLTokenType, IClassificationType> typeDic;
     98         Scanner scanner = new Scanner();
     99     }
    100     #endregion //Classifier
    GLSLClassifierProvider

    TagsChanged事件保证在代码发生改变时实时刷新编辑器。

    构造方法中,通过typeService.GetClassificationType("GLSLIdentifier")取得我们定义的实例,并把它们和枚举关联起来,

    GetClassificationType的参数传入着色类型的Name。

    GetTags方法是由系统调用的迭代方法,yield return new TagSpan<ClassificationTag>()返回我们的着色对象,即可实现着色效果。

    编译并运行,可以看到vert、fraghe geom已经有了语法着色了。

    如果你实在做不出来,不如去我的Github下载源码,直接编译即可。

    2016-05-14

    根据GLSL4.3更新了GLSL的关键字、内置类型、内置变量、内置函数,添加了对“数值”的高亮显示。

    重命名为GLGLHighlight。

    为了方便换色,我把常用颜色保存到这里

  • 相关阅读:
    Netty实现Http客户端
    Netty实现Http服务端
    Netty实现Tcp客户端
    Netty实现Tcp服务端
    MySQL进阶系列:一文详解explain
    spring boot 获取运行时的yml里的active配置
    eureka 注册中心添加认证
    zuul 负载
    jenkins spring cloud
    秒杀系统如何设计?
  • 原文地址:https://www.cnblogs.com/bitzhuwei/p/glsl-syntax-highlight-in-visual-studio.html
Copyright © 2011-2022 走看看