青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

  C++博客 :: 首頁 :: 聯(lián)系 ::  :: 管理
  163 Posts :: 4 Stories :: 350 Comments :: 0 Trackbacks

常用鏈接

留言簿(48)

我參與的團(tuán)隊(duì)

搜索

  •  

積分與排名

  • 積分 - 402532
  • 排名 - 59

最新評論

閱讀排行榜

評論排行榜

這節(jié)課繼續(xù)上一節(jié)課課的內(nèi)容。在第13課我們學(xué)習(xí)了如何使用位圖字體,這節(jié)課,我們將學(xué)習(xí)如何使用輪廓字體。
創(chuàng)建輪廓字體的方法類似于在第13課中我們創(chuàng)建位圖字體的方法。但是,輪廓字體看起來要酷100倍!你可以指定輪廓字體的大小。輪廓字體可以在屏幕中以3D方式運(yùn)動,而且輪廓字體還可以有一定的厚度!而不是平面的2D字符。使用輪廓字體,你可以將你的計(jì)算機(jī)中的任何字體轉(zhuǎn)換為OpenGL中的3D字體,加上合適的法線,在有光照的時(shí)候,字符就會被很好的照亮了。

一個(gè)小注釋,這段代碼是專門針對Windows寫的,它使用了Windows的wgl函數(shù)來創(chuàng)建字體,顯然,Apple機(jī)系統(tǒng)有agl,X系統(tǒng)有g(shù)lx來支持做同樣事情的,不幸的是,我不能保證這些代碼也是容易使用的。如果哪位有能在屏幕上顯示文字且獨(dú)立于平臺的代碼,請告訴我,我將重寫一個(gè)有關(guān)字體的教程。

我們從第一課的典型代碼開始,添加上stdio.h頭文件以便進(jìn)行標(biāo)準(zhǔn)輸入/輸出操作,另外,stdarg.h頭文件用來解析文字以及把變量轉(zhuǎn)換為文字。最后加上math.h頭文件,這樣我們就可以使用SIN和COS函數(shù)在屏幕中移動文字了。
 
  
  
 另外,我們還要添加2個(gè)變量。base將保存我們創(chuàng)建的第一個(gè)顯示列表的編號。每個(gè)字符都需要有自己的顯示列表。例如,字符‘A’在顯示列表中是65,‘B’是66,‘C’是67,等等。所以,字符‘A’應(yīng)保存在顯示列表中的base + 65這個(gè)位置。
我們再添加一個(gè)叫做rot的變量。用它配合SIN和COS函數(shù)在屏幕上旋轉(zhuǎn)文字。我們同時(shí)用它來改變文字的顏色。

 
  

GLuint    base;            // 繪制字體的顯示列表的開始位置
GLfloat    rot;            // 旋轉(zhuǎn)字體

  
 GLYPHMETRICSFLOAT gmf[256]用來保存256個(gè)輪廓字體顯示列表中對應(yīng)的每一個(gè)列表的位置和方向的信息。我們通過gmf[num]來選擇字母。num就是我們想要了解的顯示列表的編號。在稍后的代碼中,我將說明如何如何檢查每個(gè)字符的寬度,以便自動將文字定位在屏幕中心。切記,每個(gè)字符的寬度可以不相同。Glyphmetrics會大大簡化我們的工作。 
  

GLYPHMETRICSFLOAT gmf[256];    // 記錄256個(gè)字符的信息

  
 下面這段用來構(gòu)建真正的字體的代碼類似于我們創(chuàng)建位圖字體的方法。和13課一樣,只是使用wglUseFontOutlines函數(shù)替換wglUseFontBitmaps函數(shù)。
 
  

base = glGenLists(256);                        // 創(chuàng)建256個(gè)顯示列表   
wglUseFontOutlines(    hDC,                    // 設(shè)置當(dāng)前窗口設(shè)備描述表的句柄
                0,                // 用于創(chuàng)建顯示列表字體的第一個(gè)字符的ASCII值
                255,                // 字符數(shù)
                base,                // 第一個(gè)顯示列表的名稱

  
 That's not all however. We then set the deviation level. The closer to 0.0f, the smooth the font will look. After we set the deviation, we get to set the font thickness. This describes how thick the font is on the Z axis. 0.0f will produce a flat 2D looking font and 1.0f will produce a font with some depth.

The parameter WGL_FONT_POLYGONS tells OpenGL to create a solid font using polygons. If we use WGL_FONT_LINES instead, the font will be wireframe (made of lines). It's also important to note that if you use GL_FONT_LINES, normals will not be generated so lighting will not work properly.

The last parameter gmf points to the address buffer for the display list data.  
  

                0.0f,                // 字體的光滑度,越小越光滑,0.0為最光滑的狀態(tài)
                0.2f,                // 在z方向突出的距離
                WGL_FONT_POLYGONS,            // 使用多邊形來生成字符,每個(gè)頂點(diǎn)具有獨(dú)立的法線
                gmf);                //一個(gè)接收字形度量數(shù)據(jù)的數(shù)組的地址,每個(gè)數(shù)組元素用它對應(yīng)的顯示列表字符的數(shù)據(jù)填充
}

  
 The following code is pretty simple. It deletes the 256 display lists from memory starting at the first list specified by base. I'm not sure if Windows would do this for you, but it's better to be safe than sorry :)  
  

GLvoid KillFont(GLvoid)                        // 刪除顯示列表
{
     glDeleteLists(base, 256);                    // 刪除256個(gè)顯示列表
}

  
 下面就是我優(yōu)異的GL文字程序了。你可以通過調(diào)用glPrint(“需要寫的文字”)來調(diào)用這段代碼。文字被存儲在字符串text[]中。 
  

GLvoid glPrint(const char *fmt, ...)                    // 自定義GL輸出字體函數(shù)
{

  
 下面的第一行定義了一個(gè)叫做length的變量。我們使用這個(gè)變量來查詢字符串的長度。第二行創(chuàng)建了一個(gè)大小為256個(gè)字符的字符數(shù)組,里面保存我們想要的文字串。第三行創(chuàng)建了一個(gè)指向一個(gè)變量列表的指針,我們在傳遞字符串的同時(shí)也傳遞了這個(gè)變量列表。如果我們傳遞文字時(shí)也傳遞了變量,這個(gè)指針將指向它們。 
  

    float        length=0;                    // 查詢字符串的長度
    char        text[256];                // 保存我們想要的文字串
    va_list        ap;                    // 指向一個(gè)變量列表的指針

  
 下面兩行代碼檢查是否有需要顯示的內(nèi)容,如果什么也沒有,屏幕上也就什么都沒有。
 
  

    if (fmt == NULL)                        // 如果無輸入則返回
        return;                   
  
 接下來三行代碼將文字中的所有符號轉(zhuǎn)換為它們的字符編號。最后,文字和轉(zhuǎn)換的符號被存儲在一個(gè)叫做“text”的字符串中。以后我會多解釋一些有關(guān)字符的細(xì)節(jié)。 
  

    va_start(ap, fmt);                        // 分析可變參數(shù)
        vsprintf(text, fmt, ap);                // 把參數(shù)值寫入字符串
    va_end(ap);                        // 結(jié)束分析

  
 感謝Jim Williams對下面一段代碼的建議。以前我是用手工將文字置于中心的,而他的辦法要好的多。
我們從一個(gè)循環(huán)開始,它將逐個(gè)檢查文本中的字符。我們通過strlen(text)得到文本的長度。設(shè)置好了循環(huán)以后,我們將通過加上每個(gè)字符的長度來增加length的值。當(dāng)循環(huán)結(jié)束以后,被保存在length中的值就是整個(gè)字符串的長度。所以,如果我們要寫的是“hello”,假設(shè)每個(gè)字符的長度都為10個(gè)單位,我們先給length的值加上第一個(gè)字母的長度10。然后,我們檢查第二個(gè)字母的長度,它的長度也是10,所以length就變成10 + 10(20)。當(dāng)我們檢查完所有5個(gè)字母以后,length的值就會等于50(5 *10)。

給出我們每個(gè)字符的長度的代碼是gmf[text[loop]].gmfCellIncX。記住,gmf存儲了我們每個(gè)顯示列表的信息。如果loop等于0,text[loop]就是我們的字符串中的第一個(gè)字符。如果loop等于1,text[loop]就是我們的字符串中的第二個(gè)字符。gmfCellIncX告訴我們被選擇的字符的長度。GmfCellIncX表示顯示位置從已繪制上的上一個(gè)字符向右移動的真正距離,這樣,字符之間就不會重疊在一起。同時(shí),這個(gè)距離就是我們想得到的字符的寬度。你還可以通過gmfCelllncY命令來得到字符的高度。如果你是在垂直方向繪制文本而不是在水平方向時(shí),這會很方便。

 
  

    for (unsigned int loop=0;loop<(strlen(text));loop++)    // 查找整個(gè)字符串的長度
    {
        length+=gmf[text[loop]].gmfCellIncX;       
    }

  
 最后我們?nèi)〕鲇?jì)算后得到的length,并把它變成負(fù)數(shù)(因?yàn)槲覀円獙⑽谋緩钠聊恢行淖笠茝亩颜麄€(gè)文本置于屏幕中間)。然后我們把length除以2。我們并不想移動整個(gè)文本的長度,只需要一半! 
  

    glTranslatef(-length/2,0.0f,0.0f);            // 把字符串置于最左邊

  
 然后我們將GL_LIST_BIT壓入屬性堆棧,它會防止glListBase影響到我們的程序中的其它顯示列表 
  

    glPushAttrib(GL_LIST_BIT);                // 把顯示列表屬性壓入屬性堆棧
    glListBase(base);                    // 設(shè)置顯示列表的基礎(chǔ)值為0

  
 現(xiàn)在OpenGL知道字符的存放位置了,我們就可以讓它在屏幕上顯示文字了。GlCallLists會調(diào)用多個(gè)顯示列表從而把整個(gè)文字的內(nèi)容同時(shí)顯示在屏幕上。
下面的代碼做后續(xù)工作。首先,它告訴OpenGL我們將要在屏幕上顯示出顯示列表中的內(nèi)容。Strlen(text)函數(shù)用來計(jì)算我們將要顯示在屏幕上的文字的長度。然后,OpenGL需要知道我們允許發(fā)送給它的列表的最大值。我們依然不能發(fā)送長度大于255的字符串。所以我們使用UNSIGNED_BYTE。(用0 - 255來表示我們需要的字符)。最后,我們通過傳遞字符串文字告訴OpenGL顯示什么內(nèi)容。

也許你想知道為什么字符不會彼此重疊堆積在一起。那時(shí)因?yàn)槊總€(gè)字符的顯示列表都知道字符的右邊緣在那里,在寫完一個(gè)字符后,OpenGL自動移動到剛寫過的字符的右邊,在寫下一個(gè)字或畫下一個(gè)物體時(shí)就會從GL移動到的最后的位置開始,也就是最后一個(gè)字符的右邊。

最后,我們將GL_LIST_BIT屬性彈出堆棧,將GL恢復(fù)到我們使用glListBase(base)設(shè)置base之前的狀態(tài)。

 
  

    glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);    // 調(diào)用顯示列表繪制字符串
    glPopAttrib();                    // 彈出屬性堆棧
}
  
 下面就是畫圖的代碼了。我們從清除屏幕和深度緩存開始。我們調(diào)用glLoadIdentity()來重置所有東西。然后我們將坐標(biāo)系向屏幕里移動十個(gè)單位。輪廓字體在透視圖模式下表現(xiàn)非常好。你將文字移入屏幕越深,文字開起來就更小。文字離你越近,它看起來就更大。
也可以使用glScalef(x,y,z)命令來操作輪廓字體。如果你想把字體放大兩倍,可以使用glScalef(1.0f,2.0f,1.0f). 2.0f 作用在y軸, 它告訴OpenGL將顯示列表的高度繪制為原來的兩倍。如果2.0f作用在x軸,那么文本的寬度將變成原來的兩倍。

 
  

int DrawGLScene(GLvoid)                    // 此過程中包括所有的繪制代碼
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 清除屏幕及深度緩存
    glLoadIdentity();                    // 重置當(dāng)前的模型觀察矩陣
    glTranslatef(0.0f,0.0f,-10.0f);            // 移入屏幕一個(gè)單位

  
 在向屏幕里移動以后,我們希望文本能旋轉(zhuǎn)起來。下面3行代碼用來在3個(gè)軸上旋轉(zhuǎn)屏幕。我將rot乘以不同的數(shù),以便每個(gè)方向上的旋轉(zhuǎn)速度不同。 
  

    glRotatef(rot,1.0f,0.0f,0.0f);            // 沿X軸旋轉(zhuǎn)
    glRotatef(rot*1.5f,0.0f,1.0f,0.0f);            // 沿Y軸旋轉(zhuǎn)
    glRotatef(rot*1.4f,0.0f,0.0f,1.0f);            // 沿Z軸旋轉(zhuǎn)

  
 下面是令人興奮的顏色循環(huán)了。照常,我們使用唯一遞增的變量(rot)。顏色通過使用COS和SIN來循環(huán)變化。我將rot除以不同的數(shù),這樣每種顏色會以不同的速度遞增。最終的效果非常好。
 
  

    // 根據(jù)字體位置設(shè)置顏色
    glColor3f(1.0f*float(cos(rot/20.0f)),1.0f*float(sin(rot/25.0f)),1.0f-0.5f*float(cos(rot/17.0f)));

  
 我最喜歡的部分,將文字寫到屏幕上。我使用同將位圖字體寫到屏幕上相同的函數(shù)。將文字寫在屏幕上,所有你要做的就是glPrint(“你想寫的文字”)。很簡單。
在下面的代碼中,我們要寫的是NeHe,空格,破折號,空格,然后是rot的值除以50后的結(jié)果(為了減慢計(jì)數(shù)器)。如果這個(gè)數(shù)大于999.99,左邊第四個(gè)數(shù)將被去掉(我們要求只顯示小數(shù)點(diǎn)左邊3位數(shù)字)。只顯示小數(shù)點(diǎn)右邊的兩位數(shù)字。
 
  

     glPrint("NeHe - %3.2f",rot/50);                // 輸出文字到屏幕

  
 然后增大旋轉(zhuǎn)變量從而改變顏色并旋轉(zhuǎn)文字。 
  
posted on 2007-12-14 14:27 sdfasdf 閱讀(291) 評論(0)  編輯 收藏 引用

只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美精品电影在线| 男女视频一区二区| 久久精品国产久精国产思思| 一区二区免费看| 中日韩高清电影网| 欧美电影在线观看完整版| 久久久久99| 亚洲激情视频在线| 国产日韩欧美一区在线 | 久久先锋影音| 久久影院午夜片一区| 麻豆freexxxx性91精品| 日韩一区二区精品| 亚洲欧美久久久久一区二区三区| 亚洲欧美日韩一区二区三区在线| 欧美午夜在线| 国产一区二区三区黄| 最新热久久免费视频| 午夜精品短视频| 一区二区高清在线| 久久国产99| 欧美性大战久久久久久久| 亚洲二区免费| 久久精品免费电影| 亚洲欧美影音先锋| 欧美国产亚洲另类动漫| 亚洲精品日韩激情在线电影| 亚洲欧美成人| 国产精品久久久久久久久免费| 国产色视频一区| 午夜精品福利电影| 欧美色网一区二区| 亚洲一区美女视频在线观看免费| 久久激情综合网| 午夜日韩电影| 一区二区免费在线观看| 欧美aa国产视频| 亚洲国产精品综合| 蜜臀av一级做a爰片久久 | 亚洲欧美日韩精品综合在线观看| 欧美激情一区二区久久久| 久久久欧美精品| 国产日产精品一区二区三区四区的观看方式 | 久久久久久久高潮| 国产精品一区二区三区四区 | 国产精品h在线观看| 欧美成人影音| 亚洲国产精品成人一区二区 | 亚洲毛片播放| 亚洲综合精品自拍| 国产老女人精品毛片久久| 久久精品99国产精品日本| 亚洲综合色激情五月| 在线欧美三区| 中文在线一区| 黄色精品网站| 亚洲一级在线观看| 亚洲大胆av| 国产精品国产一区二区| 欧美伊人影院| 欧美日韩视频| 欧美电影在线| 久久久国产精品亚洲一区 | 亚洲一区二区三区在线观看视频| 久久精品欧美| 正在播放亚洲一区| 亚洲视频一二区| 日韩一级在线观看| 麻豆精品在线视频| 麻豆久久婷婷| 国产精品一级久久久| 亚洲国产第一页| 在线观看国产精品网站| 久久这里有精品15一区二区三区| 欧美 日韩 国产精品免费观看| 欧美午夜美女看片| 久久精品中文字幕免费mv| 欧美视频一区二区三区| 亚洲经典在线看| 日韩亚洲欧美一区| 欧美片在线观看| 欧美国产丝袜视频| 亚洲视频精品| 欧美日韩免费一区二区三区视频| 欧美暴力喷水在线| 99精品国产一区二区青青牛奶| 亚洲人永久免费| 蜜桃av综合| 99精品热6080yy久久 | 国产综合香蕉五月婷在线| av成人免费观看| 欧美亚洲视频| 国产一区二区欧美| 媚黑女一区二区| 亚洲一区二区三区三| 欧美久久电影| 欧美在线黄色| 中文日韩电影网站| 蜜月aⅴ免费一区二区三区| 在线观看视频一区二区| 国产精品美女主播| 欧美激情第一页xxx| 久久国产精品99国产精| 中文网丁香综合网| 国产日韩欧美不卡| 国产精品免费在线| 欧美视频在线免费| 亚洲欧美日韩人成在线播放| 亚洲精选成人| 亚洲国产日韩欧美在线99| 黄色成人免费观看| 1769国产精品| 亚洲黄网站黄| 99精品福利视频| 一区二区三区视频在线| 亚洲影院色无极综合| 亚洲视频一区二区| 午夜免费在线观看精品视频| 亚洲欧美日韩国产精品| 欧美在线综合视频| 浪潮色综合久久天堂| 欧美精品99| 国产精品美女在线| 国产亚洲综合在线| 国产精品红桃| 亚洲大胆人体视频| 亚洲最快最全在线视频| 亚洲午夜精品在线| 欧美影院成年免费版| 久久男人av资源网站| 欧美黄在线观看| 亚洲精选在线| 久久精品一二三| 欧美精品一区在线观看| 国产片一区二区| 久久久久久久激情视频| 欧美精品aa| 最新国产の精品合集bt伙计| 亚洲午夜羞羞片| 欧美激情精品久久久久久| 亚洲天天影视| 欧美区在线播放| 亚洲人被黑人高潮完整版| 久久精品99久久香蕉国产色戒| 欧美激情在线| 欧美精品在欧美一区二区少妇| 欧美视频精品在线| 妖精视频成人观看www| 亚洲第一在线综合在线| 久久国产一二区| 亚洲高清久久| 亚洲国产视频直播| 欧美精品在线播放| 亚洲欧美精品一区| 亚洲影视综合| 国产亚洲在线观看| 毛片一区二区三区| 欧美成人免费va影院高清| 99爱精品视频| 午夜精品区一区二区三| 国产日本欧美一区二区三区| 久久一区二区视频| 欧美成人一区二区三区在线观看 | 亚洲欧美成人精品| 国产视频一区免费看| 麻豆91精品| 亚洲深夜av| 在线一区日本视频| 亚洲一区二区三区在线播放| 欧美日韩高清一区| 久久精彩免费视频| 欧美日韩国产一区二区| 欧美在线观看视频在线| 免费日韩视频| 奶水喷射视频一区| 国产一区二区久久| 亚洲午夜精品17c| 日韩视频久久| 毛片av中文字幕一区二区| 欧美日韩国产综合视频在线观看中文 | 欧美亚洲不卡| 亚洲成人资源网| 日韩亚洲在线观看| 亚洲一区三区电影在线观看| 久热国产精品视频| 亚洲欧美日韩中文播放| 欧美视频一区二区| 久久久亚洲一区| 亚洲成色www8888| 国产精品九九久久久久久久| 欧美亚洲一区二区在线| 亚洲国产精品成人va在线观看| 亚洲伊人色欲综合网| 国产精品jvid在线观看蜜臀| 亚洲欧美成人网| 亚洲国产精品视频一区| 亚洲欧美日韩爽爽影院| 精品av久久久久电影| 国产精品久久久久国产精品日日| 亚洲最快最全在线视频|