描かれたテキストをsharpgl

序文
表示テキストに言えば、我々はすべてのフィーリングは非常に簡単であると推定されます。OpenGLのプロフェッショナル・グラフィックス技術として、でも表示テキスト・インターフェースがありません。その後、詳細な調査後の調査結果は、テキストが非常に難しい問題であることを示唆しています。低レベルAPIとしてOpenGLは、対応するインタフェースを提供するのに適していません。
ビルドへの環境
我々が開始する前に、我々は、開発環境をセットアップする必要があります。OpenGLはC ++インターフェイスである、C#は、彼らが呼び出すことができる前にパッケージ化する必要があります。OpenGLのための多くのパッケージがありますが、私たちはSharpGLライブラリとして選択しました。次のように具体的な手順は次のとおりです。
ウィンドウプロシージャを作成します。
 NUGetはSharpGLとSharpGL.WinForms内に設置しました。

SharpFont.DependenciesとSharpFontをインストールします。3.。
 
これは、FreeTypeライブラリ、インストール時に注意を払うで、依存関係の依存関係を無視することを選択しました。
 
。FreeFont.zipコンパイルされFreeType.dll、ダウンロードの導入は、
 プログラムにFreeFont.dllを導入:

3. [追加変更制御によるSharpGL。OpenGLControlは、ツールボックスから直接ドラッグすることはできません窓、手動で変更する必要.designer.cs
部分クラスのForm1 {/// <要約> ///必要な設計変数。/// </要約>プライベートSystem.ComponentModel.IContainerコンポーネント= NULL; ///使用されているすべてのリソースをアップ<要約> ///クリーン。/// </要約> ///ます。<param name = "処分">管理対象リソースは、真でなければならない場合には、それ以外の場合はfalse。</ PARAM>保護オーバーライドボイド廃棄(BOOLが配置){もし{あるcomponents.Dispose()((成分= NULL)&&配置!);} base.Dispose(配置);} #region Windowsフォームデザイナ生成されたコード/// <要約>デザイナーのサポートのために必要な///方法 - ///このメソッドの内容を変更するコードエディタを使用して変更しないでください。/// </要約>ます。private void InitializeComponentの(){this.openGLControl1 =新しいSharpGL。OpenGLControl(); ((System.ComponentModel.ISupportInitialize)(this.openGLControl1))BeginInitの()。this.SuspendLayout(); // // // openGLControl1 this.openGLControl1.Dock = System.Windows.Forms.DockStyle.Fill。this.openGLControl1.DrawFPS =はtrue。this.openGLControl1.FrameRate = 50。this.openGLControl1.Location =新しいSystem.Drawing.Point(0、0); this.openGLControl1.Name = "openGLControl1"。this.openGLControl1.OpenGLVersion = SharpGL.Version.OpenGLVersion.OpenGL2_1。this.openGLControl1.RenderContextType = SharpGL.RenderContextType.NativeWindow。this.openGLControl1.RenderTrigger = SharpGL.RenderTrigger.Manual。this.openGLControl1.Size =新しいSystem.Drawing.Size(563、473)。this.openGLControl1.TabIndex = 0; this.openGLControl1.OpenGLInitialized + =新しいSystem.EventHandler(this.openGLControl1_OpenGLInitialized)。this.openGLControl1.OpenGLDraw + =新しいSharpGL.RenderEventHandler(this.openGLControl1_OpenGLDraw)。this.openGLControl1.Resized + =新しいSystem.EventHandler(this.openGLControl1_Resized)。this.openGLControl1.MouseDown + =新しいSystem.Windows.Forms.MouseEventHandler(this.openGLControl1_MouseDown)。this.openGLControl1.MouseMove + =新しいSystem.Windows.Forms.MouseEventHandler(this.openGLControl1_MouseMove)。this.openGLControl1.MouseUp + =新しいSystem.Windows.Forms.MouseEventHandler(this.openGLControl1_MouseUp)。// // // Form1のthis.AutoScaleDimensions =新しいSystem.Drawing.SizeF(6F、12F)。this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font。this.ClientSize =新しいSystem.Drawing.Size(563、473)。this.Controls.Add(this.openGLControl1)。this.Name = "Form1の"; this.Text = "Form1の"; ((System.ComponentModel.ISupportInitialize)(this.openGLControl1))EndInit()。this.ResumeLayout(偽); } #endregionプライベートSharpGL.OpenGLControl openGLControl1。} this.ResumeLayout(偽); } #endregionプライベートSharpGL.OpenGLControl openGLControl1。} this.ResumeLayout(偽); } #endregionプライベートSharpGL.OpenGLControl openGLControl1。
 
 
達成するための機能
フィージビリティ
リストショー
OpenGLのディスプレイリストは、一般的なシナリオで、彼は、リスト内の結果の形を保存し、必要なときにこのリストを直接呼び出して、その効果は非常に明確であることができます。
 
図は、単語リストが表示されています。以下は、特定のコードです
 プライベートボイドdrawCNString(文字列str、フロートX、フロートY、INTのfontSize、OpenGLのGL){int型I。//フェース名に基づいてフォントを作成します。VAR HFONT = Win32.CreateFont(のfontSize、0、0、0、Win32.FW_DONTCARE、0、0、0、Win32.DEFAULT_CHARSET、Win32.OUT_OUTLINE_PRECIS、Win32.CLIP_DEFAULT_PRECIS、Win32.CLEARTYPE_QUALITY、Win32.CLEARTYPE_NATURAL_QUALITY、 "新宋体") ; //フォントハンドルを選択します。VAR hOldObject = Win32.SelectObject(gl.RenderContextProvider.DeviceContextHandle、HFONT)。//リストのベースを作成します。VAR一覧= gl.GenLists(1)。gl.RasterPos(X、Y)//逐个输出字符(I = 0、I <str.Length; ++ i)について{BOOL結果= Win32.wglUseFontBitmapsW(gl.RenderContextProvider。DeviceContextHandle、STR [i]は、1リスト)。gl.CallList(リスト); } //回收所有临时资源//フリー(wstringの)。gl.DeleteLists(リスト1)。//古いフォントを選択し直し。Win32.SelectObject(gl.RenderContextProvider.DeviceContextHandle、hOldObject)。//フリーフォント。Win32.DeleteObject(HFONT)。// glDeleteLists(リスト、1); }
APIwglUseFontBitmapオペレーティングシステムは各コールのリストが生成されつつあるのでOpenGLは、多くて256以上の記憶された最大数の一覧が表示されます。ディスプレイの文字が問題で、あなたは一回限りのショーのすべてのリストを生成することができませんが、中国はテキスト表示リスト生成の全てを進めることができないだろう、すべての選択肢は、その効率が大幅に削減されますので、彼を示してすぐに、文字のリストを生成することです。
別の障害は乗り越えられないで、この表示リストが結果として生成され、まだかなりのベクターよりも、ビットマップのピクセルレベルを探します。彼はズームインまたはズームアウトすることができない原因。
         概要:この方法は、血液か何かを表示するようにゲームのメニュー、などの問題に適しています。しかし、図面上のテキストを表示するのに適していません。
ベクタフォントやビットマップフォント
初期のOpenGLの手順では、多くの場合、表示フォントのビットマップを通ってくる、開発の年として、TrueTypeフォント、TrueTypeフォントのより一層の活用。しかし、TrueTypeフォントで、フォント自体が直接頻繁にして、テクスチャに道によって画面にテクスチャ氏で、OpenGLで表示されません。テクスチャやビットマップは、簡単に言えば、まだ表示フォントのビットマップなしで行うことはできません。
システムのデフォルトのフォントやFreeTypeの
文字ビットマップを生成し、デフォルトSystem.Texting.Font FreeTypeライブラリを使用することができるシステムを使用することもできます。しかし、前者はあなたが使用する前に既にインストールされている対応するネイティブフォントが必要です。後者は直接フォントファイルをロードすることができ、のFreeTypeを選択することをお勧めします。
グラフィックフォント
また、AutoCADはまた、グリフフォント(.SHXファイル)をサポートし、この文書はどこ長く描き、その後、ペンを持ち上げるためにどの方向そして、テキストを書き込むには、標準サイズで記述し、繰り返しまま、書かれた単語を知っています、私たちは基本的に同じで書きます。
このように関係なく非常に明確なものになるかどうか、実際のベクトルフォント、ズームテキストです。描画が完全に解析された後、同様に、あなたは再レンダリングのフォントする必要はありません。
しかし、彼は彼の欠点を持って、彼は図面を書くのは10,000語がある場合、あなたは固定小数点座標の光何百万を書いて取る必要があり、多くの場合、ペンの書き込み数十(二点に相当する合計)に必要な単語です。一定の圧力があるメモリがあります。
第二の欠点は、彼が線で表示テキストに使用されているため、描画彼のこぎりを拡大、ということである行の一つです。
そうであっても、グラフィカルなフォントも良い代替かもしれません。
穀物
テクスチャは単語画像を生成することを、より信頼性の高い方式で、テクスチャ手段であり、これらの写真はその後に対応する位置に表示されます。
ファイルが少ない1M以上出て保存、およびメモリのダースMについて取り上げ、カードポートにロードされたPNG、ビットマップを生成するために18個のピクセルに基づいて、テストして1000の漢字。
問題が発生しました
演奏
図面は、単語の数千人の推定数十の規定の数万人を有していてもよく考慮に入れると、回避する必要性はすべての問題を再生成されますが、キャッシュの完全な使用は、より良い方法は、レンダリングされた完全な図面を使用テクスチャ、頂点バッファ、VBO VAOの技術であります。
メモリ
ダースとメモリM一度テクスチャが、私たちは無限にテクスチャを生成することができないが、例えば8つのピクセル101216182436再びテクスチャを生成します。
スケーリング
もう一つの問題は、テキスト表示のスケーリングは、漠然とに減少グリッチがあるときにズームしていることです。
フリッカー
あなたはテクスチャをスケーリングした後に再構築する場合、必然的な結果カトンまたは点滅。
最終案
FreeTypeの
FreeTypeのテクスチャライブラリを使用して生成テキストがSharpFontカプセル化されたC#のFreeType呼び出されたを使用することができます。
まず顔を使用する前に、オブジェクトを作成します
 公共のボイドのSetFont(文字列filename){FontFace =新しい顔(LIB、ファイル名); SetSizeメソッド(this.Size);}パブリック静的バイト[] RenderString(ライブラリライブラリ、フェイス面、文字列テキスト、W REF INT、REF INT H){VARの文字=新しいリスト<CharInfo>(); VARポーズ=新しいリスト<CharTextture>(); フロートstringWidth = 0。文字列フロートstringHeight = 0の//測定した幅です。//文字列//ボトムとトップの測定高さは、簡単にするために、両方の陽性です。.NETで//描画は右//と下向きの正のYに正のXで、左上隅に0,0を持っています。//グリフメトリックは左側にし、視覚的なデータのベースライン//で一般的に起源を持っていますが、どの象限にグリフの部分を描くことができ、そして//さえ(カーニング経由)の原点を移動します。フロートトップ= 0、底部= 0。フロートX = 0、Y = 0。int型rowStart = 0; //それをレンダリングする前に、文字列のサイズを測定します。私たちは、ビットマップ(キャンバス)の適切なサイズを作成することができます上の文字を描画する//ので、これを行う必要があります。以下のために(INT iが= 0; I <text.Length; I ++){#regionロード文字チャーC =テキスト[I]; //この文字のグリフインデックスを検索します。UINTたglyphIndex = face.GetCharIndex(C); //フォントのグリフスロットにグリフをロードします。スロットは1つだけのフォントで、通常はあります。face.LoadGlyph(たglyphIndex、LoadFlags.Default、LoadTarget.Normal)。VAR lineHeight = face.Glyph.LinearVerticalAdvance.Value。// http://www.freetype.org/freetype2/docs/tutorial/step2.htmlで「グリフメトリクス」と題された図を参照してください。//この例(グリフdims.svg)に含まれるグリフ図でもあります。//メトリックは、以下のスロットにロードされたグリフのためのものです。フロートgAdvanceX =(FLOAT)face.Glyph.Advance.X。メトリックgBearingX =(FLOAT)face.Glyph.Metrics.Horizo​​ntalBearingXフロート予めよう//同じ。フロートgWidth = face.Glyph.Metrics.Width.ToSingle()。フロートgHeight = face.Glyph.Metrics.Height.ToSingle()。VaRのCI =新しいCharInfo {チャー= C、X = X、Y = Y、幅= gWidth、左= gBearingX、右= gBearingX + gWidth、AdvanceX = gAdvanceX、トップ=(フロート)face.Glyph.Metrics.Horizo​​ntalBearingY、ボトム=(フロート)(gHeight - face.Glyph.Metrics.Horizo​​ntalBearingY)}; ボトム#endregion #regionのトップへ/ //この文字は以前の文字より高いか低いなると、//ビットマップの全体の高さを調整します。フロートglyphTop =(FLOAT)face.Glyph.Metrics.Horizo​​ntalBearingY。フロートglyphBottom =(フロート)(face.Glyph.Metrics.Height - face.Glyph.Metrics.Horizo​​ntalBearingY)。IF(glyphTop>トップ)トップ= glyphTop。IF(glyphBottom>底)底= glyphBottom。#endregion用{(ci.X + ci.AdvanceX> MaxWidthの)IF(VARのJ = rowStart; J <I、J ++){文字[J] .Y + =頂。文字[J] = .LineTopトップ。文字[J] .LineBottom =ボトム。} Y + =トップ+ボトム。X = 0。ci.X = X。ci.Y = Y。stringHeight + =トップ+ボトム。rowStartは私を=。} X + = ci.AdvanceX。chars.Add(CI)。stringWidth = Math.Max(stringWidth、X)。//は、各文字(単純幅)の原点との距離を蓄積します。}(VARのJ = rowStartため; J <chars.Count。J ++){文字[J] .Y + =頂。文字[J] = .LineTopトップ。文字[J] .LineBottom =ボトム。} stringHeight + =トップ+ボトム。//任意の次元が0の場合、我々はビットマップを作成することはできません(stringWidth == 0 || stringHeight == 0)の戻り場合はnull; //文字列に合った新しいビットマップを作成します。= W(INT)Math.Ceiling(stringWidth)。INT、L = 2です。一方、(L <W){L * = 2; } W = L。H =(INT)Math.Ceiling(stringHeight)。L = 2。(L <H)、{L * = 2一方、} H = L。// W = 512。// H = 512。バイト[]バフ=新しいバイト[H * W * 2]。ペンborderPen = Pens.Blue。ペンshapePen = Pens.Red。//ビットマップに文字列を描画します。//これの多くは、測定手順の繰り返しですが、今回は//(グリフスロットにキャンバスとビットマップの両方)での作業に実際のビットマップを持っています。以下のために(INT iが= 0; I <chars.Count; I ++){VAR CI =文字[I]。#region負荷文字charのC = ci.Char。; 我々は)(RenderGlyph除いて、測定されたときのように//同じことがグリフデータ//ビットマップに変換されます。UINTたglyphIndex = face.GetCharIndex(C); face.LoadGlyph(たglyphIndex、LoadFlags.Default、LoadTarget.Mono)。face.Glyph.RenderGlyph(RenderMode.Normal)。FTBitmap ftbmp = face.Glyph.Bitmap。#endregionは時々ゼロサイズのビットマップが、非ゼロの進歩を持っているグリフ//空白文字を描き#region。//私たちは、0サイズのビットマップを描画することはできませんが、ペンの位置はまだ先進的な(下記)を取得します。IF((ftbmp.Width> 0 && ftbmp.Rows> 0)){VARカウント= ftbmp.Width * ftbmp.Rows。(ftbmp.PixelMode == PixelMode.Mono){// StringBuilderのSB =新規のStringBuilder()であれば、int型CW = ftbmp.Width / 8。IF(CW * 8 <ftbmp.Width){CW ++。}の(VARのR = 0; R <ftbmp.Rows; R ++){用(VARのCOL = 0、COL <ftbmp.Width; COL ++){VARビット= COLの%8。VAR咬傷=(COL - ビット)/ 8。バイトPIX = ftbmp.BufferData [R * CW +一口]。VAR toCheck = PIX >>(7 - ビット)。BOOL hasClr =(toCheck&1)== 1。VAR P =(INT)Math.Ceiling((ci.Y - ci.Top + R)* W + ci.X + ci.Left + COL)。IF(hasClr){バフ[P * 2] = 255。バフ[P * 2 + 1] = 255。}}} // VAR形状= sb.ToString()。}そうであれば(ftbmp.PixelMode == PixelMode.Gray){用(VARのJ = 0; J <ftbmp.Rows; J ++){用(VARのK = 0; K <ftbmp.Widthあり、k ++){VARのPOS = J * ftbmp.Width + K; VARのP =(INT)Math.Ceiling((ci.Y - ci.Top + jの)* W + ci.X + ci.Left + K)。VAR G =(INT)ftbmp.BufferData [POS]。もし(G> 0){IF(G <100){G =(INT)Math.Ceiling(G * 2F)。}他{G =(INT)Math.Ceiling(G * 1.5F)。}場合(G> 255){G = 255。}バフ[P * 2] = 255。バフ[P * 2 + 1] =(バイト)G。}}}} ftbmp.Dispose()。} poses.Add(新しいCharTextture {チャー= C、左=(FLOAT)ci.X /トップ、W =(フロート)(ci.Y - ci.LineTop)/ H、右=(フロート)(ci.X + ci.AdvanceX)/ W、ボトム=(フロート)(ci.Y + ci.LineBottom)/ H、WidthScale = ci.AdvanceX /(ci.LineTop + ci.LineBottom)})。#endregion} LastPoses =ポーズ。バフを返します。} ボトム=(フロート)(ci.Y + ci.LineBottom)/ H、WidthScale = ci.AdvanceX /(ci.LineTop + ci.LineBottom)})。#endregion} LastPoses =ポーズ。バフを返します。} ボトム=(フロート)(ci.Y + ci.LineBottom)/ H、WidthScale = ci.AdvanceX /(ci.LineTop + ci.LineBottom)})。#endregion} LastPoses =ポーズ。バフを返します。}
その後、LoadGlyph法でフォント情報をロードします。
UINTたglyphIndex = face.GetCharIndex(C);
         face.LoadGlyph(たglyphIndex、LoadFlags.Default、LoadTarget.Normal)。
         VAR lineHeight = face.Glyph.LinearVerticalAdvance.Value。
face.Glyph.RenderGlyph(RenderMode.Normal)。
         FTBitmap ftbmp = face.Glyph.Bitmap。
必要に区別する場合には、直接bufferData ftBmp情報がフォントに対応することによって得ることができるが、それはビットフォントが格納されている、モノ語にレンダリングモードと、ことに留意すべきである、他のバイトに格納されたフォント情報を読み出し御馳走
(ftbmp.PixelMode == PixelMode.Mono){// StringBuilderのSB =新規のStringBuilder()であれば、int型CW = ftbmp.Width / 8。IF(CW * 8 <ftbmp.Width){CW ++。}の(VARのR = 0; R <ftbmp.Rows; R ++){用(VARのCOL = 0、COL <ftbmp.Width; COL ++){VARビット= COLの%8。VAR咬傷=(COL - ビット)/ 8。バイトPIX = ftbmp.BufferData [R * CW +一口]。VAR toCheck = PIX >>(7 - ビット)。BOOL hasClr =(toCheck&1)== 1。VAR P =(INT)Math.Ceiling((ci.Y - ci.Top + R)* W + ci.X + ci.Left + COL)。IF(hasClr){バフ[P * 2] = 255。バフ[P * 2 + 1] = 255。}}} // VAR形状= sb.ToString()。}そうであれば(ftbmp.PixelMode == PixelMode.Gray){用(VARのJ = 0; J <ftbmp.Rows; J ++){用(VARのK = 0; K <ftbmp.Widthあり、k ++){VARのPOS = J * ftbmp.Width + K; VARのP =(INT)Math.Ceiling((ci.Y - ci.Top + jの)* W + ci.X + ci.Left + K)。VAR G =(INT)ftbmp.BufferData [POS]。IF(G> 0){IF(G <100){G =(INT)Math.Ceiling(G * 2F)。}他{G =(INT)Math.Ceiling(G * 1.5F)。}場合(G> 255){G = 255。}バフ[P * 2] = 255。バフ[P * 2 + 1] =(バイト)G。
 アルファチャネルを読み出すとき、さらに、値は、アルファチャンネルを増加させるのに適切であり得ます。
TrueTypeは、このリンクをたどることがあります。
http://www.freetype.org/freetype2/docs/tutorial/step2.html。
テクスチャ+ MIPMAP
レンダリング時に描画が減少した場合ミップマップはテクスチャをサンプリングする方法である、OpenGLのテクスチャをロードした後、あなたは、より小さな一連のテクスチャを生成することができ、小型の質感に近い、直接ではなく、元のテクスチャを使用しての直接使用。
 プライベートボイドGetMipTextureViaBuff(OpenGLのGL){fontSizes =新しいINT [] {12}。fontService.SetSize(12F)。テクスチャ=新しいUINT [fontSizes.Length]。INT W = 0、H = 0。gl.GenTextures(fontSizes.Length、テクスチャ)。VARデータ= fontService.GetTextBuff(チャー、W REF、REF H)。Coorses.Add(FontService.LastPoses)。//テクスチャをバインドします。gl.BindTexture(OpenGL.GL_TEXTURE_2D、テクスチャ[0])。gl.TexParameter(OpenGL.GL_TEXTURE_2D、OpenGL.GL_TEXTURE_WRAP_S、OpenGL.GL_CLAMP_TO_BORDER)。gl.TexParameter(OpenGL.GL_TEXTURE_2D、OpenGL.GL_TEXTURE_WRAP_T、OpenGL.GL_CLAMP_TO_BORDER)。gl.TexParameter(OpenGL.GL_TEXTURE_2D、OpenGL.GL_TEXTURE_MIN_FILTER、OpenGL.GL_LINEAR_MIPMAP_LINEAR)。gl.TexParameter(OpenGL.GL_TEXTURE_2D、OpenGL.GL_TEXTURE_MAG_FILTER、OpenGL.GL_LINEAR_MIPMAP_NEAREST)。gl.TexEnv(OpenGL.GL_TEXTURE_ENV、OpenGL.GL_TEXTURE_ENV_MODE、OpenGL.GL_REPLACE)。gl.TexParameter(OpenGL.GL_TEXTURE_2D、OpenGL.GL_TEXTURE_BASE_LEVEL、0); gl.TexParameter(OpenGL.GL_TEXTURE_2D、OpenGL.GL_TEXTURE_MAX_LEVEL、2)。フロート[] max_antis =新しいフロート[1]。gl.GetFloat(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT、max_antis)。//多重采样gl.TexParameter(OpenGL.GL_TEXTURE_2D、GL_TEXTURE_MAX_ANISOTROPY_EXT、max_antis [0] <4 max_antis [0]:4)。//创建ミップマップ纹理gluBuild2DMipmaps(OpenGL.GL_TEXTURE_2D、2、W、H、OpenGL.GL_LUMINANCE_ALPHA、OpenGL.GL_UNSIGNED_BYTE、データ)。// int型のサイズ=データ.LENGTH。//のIntPtrバッファ= Marshal.AllocHGlobal(サイズ)。//試し// {// Marshal.Copy(データ、0、バッファ、サイズ)// gl.Build2DMipmaps(OpenGL.GL_TEXTURE_2D、2、W、H、OpenGL.GL_LUMINANCE_ALPHA、OpenGL.GL_UNSIGNED_BYTE、バッファ); //} // //最後に{// Marshal.FreeHGlobal(バッファ)//}}
使用ミップマップテクスチャは、メモリの1/3程度まで服用することもできるが、生成後、再び生成されません。描画がより円滑に表示効果を拡大することができ、以下の通りであります:
 
シェーダ
         使用ミップマップテクスチャ、我々はその色の問題に対処する必要があります。デフォルトのシェーダテクスチャの色は、画面自体の上に表示されますが、我々のニーズはさまざまな要件に応じて各色ごとに生成されません。さまざまな色と質感で表示されます。
私たちは、シェーダによってこの問題を解決することができます。
 #regionシェーダVertexShader vertexShader =新しいVertexShader()。vertexShader.CreateInContext(GL)。vertexShader.SetSource(#バージョン130はVEC2のTEXCOORDを変える "@;変vec4 pass_color、ボイドメイン(ボイド){gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(gl_Vertex.xy、0,1); // ftransform(); // TEXCOORD = gl_Vertex.zw; pass_color = GL_COLOR;} ")。//フラグメントシェーダを作成します。FragmentShader fragmentShader =新しいFragmentShader(); fragmentShader.CreateInContext(GL)。fragmentShader.SetSource(@ "#バージョン130varying VEC2のTEXCOORD、変化vec4のpass_color、均一sampler2Dテックス;均一vec4色、ボイドメイン(ボイド){vec4 CLR =にTexture2D(TEX、TEXCOORD); // TEXCOORD gl_FragColor = vec4(1,1 、1、clr.a)* pass_color;} ")。//それらの両方をコンパイルします。vertexShader.Compile(); ストリングMSG = GetShaderError(vertexShader.ShaderObject、GL)。(!string.IsNullOrEmpty(MSG)){MessageBox.Show(MSG)であれば、} fragmentShader.Compile()。MSG = GetShaderError(fragmentShader.ShaderObject、GL)。(!string.IsNullOrEmpty(MSG)){MessageBox.Show(MSG)であれば、} //プログラムをビルドします。program.CreateInContext(GL)。//シェーダを取り付けます。program.AttachShader(vertexShader)。program.AttachShader(fragmentShader)。program.Link(); INT [] PARM =新しいint型[1]; gl.GetProgram(program.ProgramObject、OpenGL.GL_LINK_STATUS、PARM)。IF(PARM [0] == 0){StringBuilderのSMSG =新規のStringBuilder(1024)。IntPtr PTR = IntPtr.Zero; gl.GetProgramInfoLog(program.ProgramObject 1024、PTR、SMSG)。MSG = smsg.ToString()。(!string.IsNullOrEmpty(MSG)){MessageBox.Show(MSG)であれば、}} gl.ValidateProgram(program.ProgramObject)。gl.GetProgram(program.ProgramObject、OpenGL.GL_VALIDATE_STATUS、PARM)。IF(PARM [0] == 0){StringBuilderのSMSG =新規のStringBuilder(1024)。IntPtr PTR = IntPtr.Zero; gl.GetProgramInfoLog(program.ProgramObject 1024、PTR、SMSG)。MSG = smsg.ToString()。(もし!文字列。IsNullOrEmpty(MSG)){MessageBox.Show(MSG)。}} #endregion
最後に表示される文字コードは次の通り:
 プライベートボイドのDrawText(文字列テキスト、フロートX、Yフロート、フロートH、フロートwscale、OpenGLのGL、BOOL bUseShader){フロートscreenH =(FLOAT)恐らくMath.round(H *スケール)。VaRのX0 = X; VAR IDX = fontSizes.Length - 1。ため(VAR I = 0; I <fontSizes.Length-1; I ++){IF(H *スケール<= fontSizeTrigers [I]){IDX = I。ブレーク; }} this.Text = "フォントサイズ:" + fontSizes [IDX] + ">" + H *スケール。クアーズ= Coorses [IDX]。INT simpler2d =(INT)テクスチャ[IDX]。gl.ActiveTexture(テクスチャ[IDX])。gl.BindTexture(OpenGL.GL_TEXTURE_2D、テクスチャ[IDX])。gl.Enable(OpenGL.GL_TEXTURE_2D)。(OpenGLをgl.Begin。GL_QUADS); foreachの(テキスト内のvar CH){VAR CI = Coors.Find(C => c.Char == CH)。W = H * ci.WidthScale * wscale VAR。(bUseShader){// gl.TexCoord(ci.Left、ci.Bottom)であれば、gl.Vertex4f(X、Y、ci.Left、ci.Bottom)。ザ・テクスチャおよびクワッド// gl.TexCoord(ci.Right、ci.Bottom)のうち//左下。gl.Vertex4f(X + W、Y、ci.Right、ci.Bottom)。ザ・テクスチャおよびクワッド// gl.TexCoord(ci.Right、ci.Top)のうち//右下。gl.Vertex4f(X + Y +はH、W、ci.Right、ci.Top)。ザ・テクスチャおよびクワッド// gl.TexCoord(ci.Left、ci.Top)の//右上。gl.Vertex4f(X、Y +はH、ci.Left、ci.Top)。他ザ・テクスチャーおよびクワッドの//左上} {gl.TexCoord(ci.Left、ci.Bottom)。gl.Vertex(X、Y、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Right、ci.Bottom)のうち//左下。gl.Vertex(X + W、Y、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Right、ci.Top)のうち//右下。gl.Vertex(X + Y +はH、W、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Left、ci.Top)の//右上。gl.Vertex(X、Y +はH、0); //テクスチャおよびクワッド}の左上X + = W。} gl.End()。gl.Disable(OpenGL.GL_TEXTURE_2D)。} 頂点(X、Y、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Right、ci.Bottom)のうち//左下。gl.Vertex(X + W、Y、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Right、ci.Top)のうち//右下。gl.Vertex(X + Y +はH、W、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Left、ci.Top)の//右上。gl.Vertex(X、Y +はH、0); //テクスチャおよびクワッド}の左上X + = W。} gl.End()。gl.Disable(OpenGL.GL_TEXTURE_2D)。} 頂点(X、Y、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Right、ci.Bottom)のうち//左下。gl.Vertex(X + W、Y、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Right、ci.Top)のうち//右下。gl.Vertex(X + Y +はH、W、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Left、ci.Top)の//右上。gl.Vertex(X、Y +はH、0); //テクスチャおよびクワッド}の左上X + = W。} gl.End()。gl.Disable(OpenGL.GL_TEXTURE_2D)。} TEXCOORD(ci.Right、ci.Top)。gl.Vertex(X + Y +はH、W、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Left、ci.Top)の//右上。gl.Vertex(X、Y +はH、0); //テクスチャおよびクワッド}の左上X + = W。} gl.End()。gl.Disable(OpenGL.GL_TEXTURE_2D)。} TEXCOORD(ci.Right、ci.Top)。gl.Vertex(X + Y +はH、W、0); ザ・テクスチャおよびクワッドgl.TexCoord(ci.Left、ci.Top)の//右上。gl.Vertex(X、Y +はH、0); //テクスチャおよびクワッド}の左上X + = W。} gl.End()。gl.Disable(OpenGL.GL_TEXTURE_2D)。}
さらなる最適化
VBO +テクスチャ
 この記事では、テクスチャとVBOの組み合わせは、より高い性能を達成するために必要があり、すぐに表示テキストに描かする唯一の方法を説明し、リアルタイムを使用しています。
最後に、ダウンロード用コードのダウンロードアドレスは(処理されて、2日以上をダウンロードできると推定されます)。
----------------
免責事項:この記事はCC 4.0 BY-SAの著作権契約書に従って、元の記事でCSDNブロガー「市八尾」で、オリジナルのソースリンクと、この文を添付してください、再現。 。
オリジナルリンクします。https://blog.csdn.net/snakegod/article/details/81126568

おすすめ

転載: www.cnblogs.com/bile/p/12183080.html