999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

OpenGL環(huán)境中二維文字的通用繪制方法?

2019-02-27 08:32:08李迎春
關(guān)鍵詞:方法

李迎春 孫 卡

(1.南昌航空大學(xué)軟件學(xué)院 南昌 330063)(2.南昌航空大學(xué)信息工程學(xué)院 南昌 330063)

1 引言

由于OpenGL沒(méi)有直接的文字(尤其是漢字)繪制支持,在需要輸出文字的地方,需要進(jìn)行特定的處理[1]。

使用OpenGL繪制文字主要有四種方法:1)使用glBitmap函數(shù)繪制單色位圖文字。吳仁彪[2]等利用多核處理器的優(yōu)勢(shì),針對(duì)實(shí)時(shí)性要求較高或進(jìn)行大批量文本數(shù)據(jù)的繪制,提出基于多線(xiàn)程的OpenGL文本繪制方法;梁麗[3]等主要研究了3D字幕技術(shù),采用OpenGL將具有視差的字母疊加在立體圖像上實(shí)現(xiàn)3D效果;李雪[4]、馬莉[5]、趙常壽[6]等采用Vega或Vega Primer與OpenGL混合編程,實(shí)現(xiàn)了Vega中漢字的二維顯示。2)使用wglUseFontBitmap函數(shù)繪制平面2D文字。芮小平[7]等研究了實(shí)現(xiàn)平面柵格字體的繪制方法;李自勝[8]研究了基于OpenGL的Windows字體處理方法,并實(shí)現(xiàn)了2D漢字的顯示。3)使用wglUseFontOutlines函數(shù)繪制3D輪廓文字。芮小平[7]、李杰[9]等結(jié)合顯示列表技術(shù)實(shí)現(xiàn)了三維輪廓字體的顯示;李雪[4]、馬莉[5]等結(jié)合Vega軟件和OpenGL圖形庫(kù),實(shí)現(xiàn)了Vega中漢字的三維顯示;李自勝[8]實(shí)現(xiàn)了三維漢字的繪制和顯示;張秀山[10]等使用OpenGL在Windows下設(shè)計(jì)與實(shí)現(xiàn)了一個(gè)三維字幕動(dòng)畫(huà)函數(shù)庫(kù)。4)使用紋理貼圖繪制紋理文字。陳飛[11]等提出基于SDL和OpenGL跨平臺(tái)圖形庫(kù),采用生產(chǎn)者-消費(fèi)者模型對(duì)中文字符串進(jìn)行處理的實(shí)時(shí)繪制方法;蘭一麟濤[12]等研究了OpenGL中的三維紋理貼圖繪制技術(shù)。另外,侯學(xué)隆[13]等研究了基于GDI的OpenGL多國(guó)文字渲染技術(shù);薛娟[14]等使用TrueType字體,實(shí)現(xiàn)了基于VxWorks的中文圖形界面設(shè)計(jì);劉亞麗[15]等提出了在VxWorks嵌入式系統(tǒng)下基于OpenGL的漢字輸入及顯示的實(shí)現(xiàn)方案。函數(shù)glBitmap只能處理單色位圖,不便修改,數(shù)據(jù)會(huì)在主存與顯存之間流動(dòng),效率不高。函數(shù)wglUseFontBitmap、wglUseFontOutlines結(jié)合顯示列表技術(shù)可以提高繪制速度,但只適用Windows操作系統(tǒng),且不提供字體修改,速度比較慢。使用紋理文字速度更快,紋理對(duì)象常駐GPU,而且能更好地控制幾何狀態(tài),使用紋理文字比使用顯示列表速度更快。

本文在綜合分析以上幾種文字繪制方法的基礎(chǔ)上,提出了一種GDI和OpenGL結(jié)合的二維文字繪制方法[16],采用面向?qū)ο蟮乃枷耄訡++作為開(kāi)發(fā)語(yǔ)言,開(kāi)發(fā)出了文字繪制的動(dòng)態(tài)鏈接庫(kù),具有較強(qiáng)的靈活性和通用性。

2 文字位圖及紋理的創(chuàng)建

2.1 文字的屬性

文字的屬性主要包括字體、字形、字號(hào)、加粗、下劃線(xiàn)、刪除線(xiàn)、顏色、邊框、位置、對(duì)齊等。Windows提供了結(jié)構(gòu)體LOGFONT來(lái)表達(dá)邏輯上的一個(gè)字體,其結(jié)構(gòu)定義如表1所示,其中l(wèi)fCharSet用來(lái)指定字符集,可以使用四種預(yù)定義值:ANSI_CHARSET,OEM_CHARSET,SYMBOL_CHARSET,UNICODE_CHARSET,CHINESEBIG5_CHARSET(繁體中文),GB2312_CHARSET(簡(jiǎn)體中文),DEFAULT_CHARSET等。

2.2 文字位圖的創(chuàng)建

基于上述字體,使用Windows GDI創(chuàng)建空白位圖,將文字在位圖中渲染,渲染后的位圖記錄了文字的輪廓信息,文字輪廓覆蓋的區(qū)域用1表示,文字輪廓未覆蓋的區(qū)域用0表示,其創(chuàng)建流程如下。

1)創(chuàng)建Windows GDI設(shè)備環(huán)境;

表1 文字的屬性

2)選擇繪制當(dāng)前文字所用的字體;

3)調(diào)用GetTextExtentPoint32函數(shù),獲得所繪文字的高度和寬度信息,該信息以像素為單位;

4)根據(jù)步驟3)獲得位圖范圍,創(chuàng)建一個(gè)內(nèi)存中的位圖對(duì)象,并把它指定到設(shè)備環(huán)境中去;

5)為設(shè)備環(huán)境指定繪圖參數(shù),如背景顏色、文字顏色、背景模式等;

6)調(diào)用Windows GDI繪圖函數(shù)TextOut在設(shè)備環(huán)境中繪圖;此時(shí)創(chuàng)建的文字位圖為設(shè)備相關(guān)位圖(DDB),此種位圖不具有自己的調(diào)色板信息,顏色模式必須與輸出設(shè)備相一致,高度依賴(lài)輸出設(shè)備,只能存在于內(nèi)存中;

7)把將設(shè)備相關(guān)位圖對(duì)象轉(zhuǎn)換為設(shè)備無(wú)關(guān)位圖(DIB),此類(lèi)位圖具有自己的調(diào)色板信息,不依賴(lài)系統(tǒng)的調(diào)色板,獨(dú)立于設(shè)備。可以使用BITMAPINFO結(jié)構(gòu)體來(lái)定義設(shè)備相關(guān)位圖和設(shè)備無(wú)關(guān)位圖的轉(zhuǎn)換規(guī)則,BITMAPINFO結(jié)構(gòu)體中的bmiHeader屬性中包含了維度和與設(shè)備無(wú)關(guān)位圖的顏色格式信息,bmiColors屬性指定了數(shù)組位圖中定義的顏色的數(shù)據(jù)類(lèi)型;

8)將轉(zhuǎn)換后的文字位圖存儲(chǔ)在一維數(shù)組中,OpenGL可以利用該位圖并調(diào)用glBitmap函數(shù)直接繪制出基于位圖的文字。由于該方法在屏幕上直接輸出的是文字的位圖信息(也稱(chēng)柵格信息),無(wú)法實(shí)現(xiàn)文字的放大、縮小、旋轉(zhuǎn)和變形等操作,為解決該問(wèn)題,需要將文字位圖轉(zhuǎn)換為文字紋理。

2.3 文字紋理的創(chuàng)建

文字紋理創(chuàng)建的思路是將2.2節(jié)所創(chuàng)建的單色位圖轉(zhuǎn)換為RGBA格式。單色位圖上的每個(gè)像素?cái)?shù)據(jù)的長(zhǎng)度為1位(即1/8個(gè)字節(jié)),文字輪廓處的數(shù)據(jù)值為二進(jìn)制的1,非輪廓處的數(shù)值為二進(jìn)制的0;RGBA格式中每個(gè)像素?cái)?shù)據(jù)的長(zhǎng)度為32位(即4個(gè)字節(jié)),以8位為1顏色單元,分別對(duì)應(yīng)顏色R、G、B、A的數(shù)值,單色位圖格式與RGBA格式的轉(zhuǎn)換如圖1所示,其步驟如下:

1)開(kāi)辟存儲(chǔ)RGBA格式數(shù)據(jù)的內(nèi)存空間,其單位為unsigned char,長(zhǎng)度為單色位圖寬度乘以高度的4倍,即每個(gè)像素點(diǎn)占據(jù)32位的空間。

2)設(shè)置當(dāng)前文字的顏色,該值使用4個(gè)字節(jié)來(lái)表示,按順序分別為R、G、B、A,每種顏色的取值范圍為[0,255];

3)按位遍歷單色位圖的數(shù)據(jù),若當(dāng)前單色位圖上數(shù)據(jù)的值為1,則將RGBA格式數(shù)據(jù)存儲(chǔ)空間上的連續(xù)4個(gè)字節(jié)用當(dāng)前的顏色值來(lái)替換;若當(dāng)前單色位圖上數(shù)據(jù)的值為0,則將RGBA格式數(shù)據(jù)存儲(chǔ)空間上的連續(xù)4個(gè)字節(jié)用(0,0,0,0)來(lái)替換;完成遍歷后,即實(shí)現(xiàn)了單色位圖到RGBA格式的轉(zhuǎn)換,轉(zhuǎn)換后的RGBA格式數(shù)據(jù)可以作為幾何圖形的紋理來(lái)使用。

圖1 單色位圖與RGBA格式的轉(zhuǎn)換

3 文字的繪制

文字繪制流程如圖2所示,先用GDI把指定的文字繪制到內(nèi)存中的Bitmap中,再把Bitmap轉(zhuǎn)換成紋理,通過(guò)修改粘貼該紋理的幾何圖形的形狀來(lái)實(shí)現(xiàn)文字的各種顯示效果。由于該方法不涉及顯示列表,在渲染常規(guī)(非變形、非旋轉(zhuǎn))文字時(shí)可以按圖形的方式輸出;在渲染非常規(guī)(變形、旋轉(zhuǎn))文字時(shí),采用紋理貼圖的方式進(jìn)行,可以繪制出傾斜、旋轉(zhuǎn)、縮放、對(duì)齊等效果。

圖2 文字的繪制流程

3.1 基于文字位圖的繪制方法

根據(jù)2.2中的步驟創(chuàng)建文字位圖之后,即可在OpenGL環(huán)境中進(jìn)行文字的繪制。使用glRaster-Pos2d(GLdouble x,GLdouble y)函數(shù)來(lái)確定所繪文字在屏幕上的位置,其中的參數(shù)x、y為繪制文字的定位點(diǎn),即該文字繪制在屏幕的何處;使用glBitmap(GLsizei width,GLsizei height,GLfloat xorig,GLfloat yorig,GLfloat xmove,GLfloat ymove,const GLubyte*bitmap)函數(shù)來(lái)實(shí)現(xiàn)位圖的繪制。使用該方法繪制出的文字可以實(shí)現(xiàn)添加邊框和對(duì)齊的特效,但無(wú)法實(shí)現(xiàn)旋轉(zhuǎn)、縮放、變形的特效。

在實(shí)現(xiàn)邊框特效時(shí),只需要根據(jù)2.2節(jié)中步驟3)中位圖寬度和高度,相對(duì)于文字定位點(diǎn)的位置,使用屏幕坐標(biāo)進(jìn)行繪制矩形即可。邊框的繪制以文字位圖的左下角的位置為參考點(diǎn)。

在實(shí)現(xiàn)對(duì)齊特效時(shí),需要根據(jù)位圖的寬度和高度對(duì)定位點(diǎn)進(jìn)行平移,通過(guò)改變定位點(diǎn)的方式,達(dá)到文字的某種對(duì)齊效果。針對(duì)不同的對(duì)齊方式,只需以像素為單位,平移0個(gè)、1/2個(gè)或1個(gè)位圖的高度和寬度即可。在本系統(tǒng)中定義了9種對(duì)齊方式,如圖3所示,其中黑色的點(diǎn)代表定位點(diǎn),對(duì)齊名稱(chēng)分別為:(a)左下對(duì)齊;(b)左中對(duì)齊;(c)左上對(duì)齊;(d)中下對(duì)齊;(e)居中對(duì)齊;(f)中上對(duì)齊;(g)右下對(duì)齊;(h)右中對(duì)齊;(i)右上對(duì)齊。

圖3 文字的對(duì)齊方式

3.2 基于文字紋理的繪制方法

為了實(shí)現(xiàn)文字的縮放、旋轉(zhuǎn)、變形等特效,需要使用紋理貼圖的方式對(duì)文字進(jìn)行繪制。使用紋理貼圖的步驟如下:

1)使用glGenTextures(GLsizei n,GLuint*textures)函數(shù),創(chuàng)建紋理ID;

2)使用glBindTextures(GLsizei n,GLuint*textures)函數(shù)實(shí)現(xiàn)紋理ID與當(dāng)前紋理的綁定;

3)使用glTexParameteri(GLenum target,GLenumpname,GLint param)函數(shù)設(shè)置紋理參數(shù);

4)使 用glTexEnvf(GLenum target,GLenum pname,GLfloat param)函數(shù)設(shè)置紋理環(huán)境;

5)使用glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid*pixels)函數(shù)實(shí)現(xiàn)內(nèi)存中紋理數(shù)據(jù)的傳遞。

6)使用glEnable(GLenum cap)函數(shù)分別啟動(dòng)紋理模式(GL_TEXTURE_2D)和透明測(cè)試模式(GL_ALPHA_TEST),并 調(diào) 用glAlphaFunc(GLenumfunc,GLclampf ref)函數(shù)設(shè)置透明貼圖。

7)使用glRotated(GLdouble angle,GLdouble x,GLdouble y,GLdouble z)函數(shù)控制所繪紋理的旋轉(zhuǎn)角度;

8)使用glScaled(GLdouble x,GLdouble y,GLdouble z)函數(shù)控制所繪文字的縮放比例;

9)使用glTexCoord2f(GLfloat s,GLfloat t)函數(shù)和glVertex2d(GLdouble x,GLdouble y)函數(shù)相結(jié)合,來(lái)控制紋理數(shù)據(jù)和幾何數(shù)據(jù)之間的坐標(biāo)映射,通過(guò)不同的映射方式,從而達(dá)到紋理變形的特效。

3.3 文字繪制類(lèi)的設(shè)計(jì)

為了實(shí)現(xiàn)文字的繪制,本文利用C++語(yǔ)言,設(shè)計(jì)了9個(gè)與繪制相關(guān)的類(lèi),并依據(jù)這些類(lèi)創(chuàng)建了動(dòng)態(tài)鏈接庫(kù),類(lèi)之間的關(guān)系如圖4所示,每個(gè)類(lèi)的功能如下:

1)頂點(diǎn)類(lèi)(CVertex):定義二維的x、y坐標(biāo),用來(lái)記錄某點(diǎn)與原點(diǎn)(0,0)的相對(duì)值。

2)顏色類(lèi)(CColor):包含四個(gè)BYTE類(lèi)型變量,表示RGBA顏色的四個(gè)分量,用來(lái)記錄顏色值。

3)包圍盒(CBoundBox):包含兩個(gè)CVertex對(duì)象,分別記錄左下角點(diǎn)和右上角點(diǎn)的位置,可以計(jì)算出所包圍對(duì)象的寬度、高度、中心點(diǎn),供繪制文字輪廓、對(duì)齊時(shí)使用。

4)位圖字體類(lèi)(CBitmapFont):用來(lái)創(chuàng)建文字的位圖,先通過(guò)其包含的LOGFONT屬性,用來(lái)設(shè)置所繪文字的字體、字形、字號(hào)、加粗、下劃線(xiàn)、刪除線(xiàn)等效果;然后調(diào)用其包含的CreateText方法,創(chuàng)建出所繪文字對(duì)應(yīng)的位圖。

5)對(duì)齊方式:對(duì)齊方式定義為枚舉類(lèi)型,記錄文本內(nèi)容與定位點(diǎn)的相對(duì)位置關(guān)系,列出了9種可選值,分別為左下對(duì)齊、左中對(duì)齊、左上對(duì)齊、中下對(duì)齊、居中對(duì)齊、中上對(duì)齊、右下對(duì)齊、右中對(duì)齊、右上對(duì)齊。

6)紋理類(lèi)(CTexture):提供將位圖數(shù)據(jù)轉(zhuǎn)換為RGBA數(shù)據(jù)的接口,記錄創(chuàng)建的紋理的寬度、高度、ID等參數(shù),只記錄紋理的參數(shù)信息,不負(fù)責(zé)紋理的繪制。

7)點(diǎn)狀要素類(lèi)(CPoint):包含一個(gè)CVertex對(duì)象,用來(lái)記錄所繪文字的定位點(diǎn),作為基類(lèi)。

8)柵格文字類(lèi)(CRasterText):用來(lái)繪制基于位圖的文字,為CPoint類(lèi)的子類(lèi),包含所繪文字的內(nèi)容、字體、顏色、對(duì)齊方式、位圖大小、是否繪制輪廓等屬性,提供設(shè)置文本、設(shè)置顏色、設(shè)置字體、計(jì)算包圍盒、平移、設(shè)置對(duì)齊方式、繪制等接口。該類(lèi)為

2.1 章節(jié)所描述繪制方法的代碼實(shí)現(xiàn)。

(9)紋理文字類(lèi)(CTextureText):用來(lái)繪制基于紋理的文字,為CRasterText類(lèi)的子類(lèi),在其父類(lèi)的基礎(chǔ)上,包含X軸上的縮放系數(shù)、Y軸上的縮放系數(shù)、旋轉(zhuǎn)角度、變形系數(shù)等屬性,提供設(shè)置旋轉(zhuǎn)角度、設(shè)置縮放系數(shù)、變形系數(shù)等接口,可以實(shí)現(xiàn)文字的旋轉(zhuǎn)、縮放、變形等特效。該類(lèi)為3.2節(jié)所描述繪制方法的代碼實(shí)現(xiàn)。

圖4 文字繪制類(lèi)關(guān)系圖

4 試驗(yàn)

本文的試驗(yàn)環(huán)境:操作系統(tǒng)Windows XPSP3簡(jiǎn)體中文專(zhuān)業(yè)版;處理器:Interl(R)Core(TM)i7-2600;屏幕分辨率為1600×900;開(kāi)發(fā)環(huán)境Visual Studio 2008;開(kāi)發(fā)語(yǔ)言:Visual C++;庫(kù)函數(shù):GDI和OpenGL;窗口背景:調(diào)用glClearColor(0,0,0,0)函數(shù),設(shè)置屏幕背景為黑色;繪制顏色:白色(255,255,255,255);對(duì)齊方式測(cè)試:文中所定義的9種對(duì)齊方式;旋轉(zhuǎn)測(cè)試:每間隔45°旋轉(zhuǎn)一次,旋轉(zhuǎn)360°;縮放測(cè)試:整體放大2倍、縮小2倍、軸向放大;傾斜測(cè)試:將文字左右各傾斜30°;變形測(cè)試:采用頂部放大和底部放大的方式,構(gòu)建出正梯形和倒梯形的文字效果;使用的邏輯字體的參數(shù)為

LOGFONTlFont;

lFont.lfHeight=32;

lFont.lfWidth=0;

lFont.lfEscapement=0;

lFont.lfOrientation=0;

lFont.lfWeight=400;

lFont.lfItalic=0;

lFont.lfUnderline=0;l

Font.lfStrikeOut=0;

lFont.lfCharSet=DEFAULT_CHARSET;

lFont.lfOutPrecision=OUT_TT_PRECIS;

lFont.lfClipPrecision= CLIP_DEFAULT_PRECIS;

lFont.lfQuality=DEFAULT_QUALITY;

lFont.lfPitchAndFamily= DEFAULT_PITCH |FF_MODERN;

strcpy_s(lFont.lfFaceName,32,“黑體”)。

本實(shí)驗(yàn)的運(yùn)行結(jié)果如圖5所示,實(shí)現(xiàn)了常規(guī)文字和非常規(guī)文字的輸出,證明了該方法的正確性和有效性。與概述中提到的其他幾種方法相比,可以方便修改文字字體、設(shè)置文字旋轉(zhuǎn)、變形、對(duì)齊方式等效果,繪制速度更快,具有很好的靈活性和通用性。

圖5 文字繪制測(cè)試結(jié)果

5 結(jié)語(yǔ)

本文介紹了OpenGL中繪制二維文字的通用方法,設(shè)計(jì)了文字繪制類(lèi)及動(dòng)態(tài)鏈接庫(kù),使用GDI實(shí)現(xiàn)了位圖文字到紋理文字的轉(zhuǎn)換,達(dá)到了文字的各種特效。該方法已經(jīng)在地圖編制、地物標(biāo)繪、信號(hào)模擬、儀表顯示等相關(guān)項(xiàng)目中得到應(yīng)用,取得了良好的效果。

猜你喜歡
方法
中醫(yī)特有的急救方法
中老年保健(2021年9期)2021-08-24 03:52:04
高中數(shù)學(xué)教學(xué)改革的方法
化學(xué)反應(yīng)多變幻 “虛擬”方法幫大忙
變快的方法
兒童繪本(2020年5期)2020-04-07 17:46:30
學(xué)習(xí)方法
用對(duì)方法才能瘦
Coco薇(2016年2期)2016-03-22 02:42:52
最有效的簡(jiǎn)單方法
山東青年(2016年1期)2016-02-28 14:25:23
四大方法 教你不再“坐以待病”!
Coco薇(2015年1期)2015-08-13 02:47:34
賺錢(qián)方法
捕魚(yú)
主站蜘蛛池模板: 亚洲欧美在线精品一区二区| 亚洲 日韩 激情 无码 中出| 亚洲成a∧人片在线观看无码| 亚洲男人天堂久久| 久久国产免费观看| 国产精品成人久久| 欧美综合中文字幕久久| 国产精品成人免费视频99| 69国产精品视频免费| 亚洲一级色| 久久亚洲国产视频| 久久鸭综合久久国产| 日本人又色又爽的视频| 亚洲国产中文欧美在线人成大黄瓜 | 欧美综合区自拍亚洲综合天堂| 美女无遮挡免费网站| 国产精品视频a| 一区二区三区高清视频国产女人| 美女国内精品自产拍在线播放| 国产成人艳妇AA视频在线| 999福利激情视频| 亚洲天堂777| 第一区免费在线观看| 国产视频欧美| 中文字幕第1页在线播| 韩日免费小视频| 2021无码专区人妻系列日韩| 免费观看精品视频999| 人妻一本久道久久综合久久鬼色| 日韩午夜福利在线观看| www.日韩三级| 久久福利网| 亚洲男人在线| 午夜视频www| 国产视频a| 1级黄色毛片| 黄色网页在线播放| 亚洲三级色| 欧美h在线观看| 国产日韩丝袜一二三区| 亚洲天堂在线视频| 亚洲91精品视频| 亚洲嫩模喷白浆| 成人综合网址| 精品视频福利| 99久久国产综合精品女同| a毛片在线播放| 午夜电影在线观看国产1区| 亚洲成人在线网| 99精品在线看| 欧美在线网| 亚洲浓毛av| 国产精品一线天| 国产精品白浆无码流出在线看| 在线欧美a| 天堂成人在线| 中文字幕亚洲电影| 蜜臀av性久久久久蜜臀aⅴ麻豆 | 国产高清在线丝袜精品一区| 亚洲精品卡2卡3卡4卡5卡区| 幺女国产一级毛片| 国产激爽大片高清在线观看| 国产极品美女在线| 日韩av电影一区二区三区四区| 无码福利视频| 久久国产高清视频| 2024av在线无码中文最新| 久久综合色视频| 国产精品3p视频| 欧美亚洲欧美| 98超碰在线观看| a免费毛片在线播放| 国产日本一区二区三区| 久久美女精品| 精品伊人久久久久7777人| 久久视精品| 国内精品视频| 97国产精品视频自在拍| 久久一日本道色综合久久 | 在线不卡免费视频| 欧美69视频在线| 国产91小视频|