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

OpenGL Texture Mapped Outline Fonts 翻譯

具有紋理貼圖的輪廓字體(Texture Mapped Outline Fonts)

  在發(fā)布了前兩篇關(guān)于位圖字體和輪廓字體的教程以后,我收到很多郵件,很多讀者都想知道如何才能給字體賦予紋理貼圖。你可以使用自動(dòng)紋理坐標(biāo)生成器。它會(huì)為字體上的每一個(gè)多邊形生成紋理坐標(biāo)。

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

  我們將使用第14課的代碼來(lái)創(chuàng)作紋理字體的演示。如果程序中哪部分的代碼有變化,我會(huì)重寫那部分的所有代碼以便看出我做的改動(dòng)。

下面這部分代碼類似于第14課的代碼,但是這次我們還要加上stdarg.h頭文件。

#include <windows.h> // Header File For Windows
#include <math.h> // Header File For Math Library
#include <stdio.h> // Header File For Standard Input/Output
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <gl\glaux.h> // Header File For The Glaux Library

HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application

bool keys[256]; // Array Used For The Keyboard Routine
bool active=TRUE; // Window Active Flag Set To TRUE By Default
bool fullscreen=TRUE; // Fullscreen Flag Set To Fullscreen Mode By Default


我們還要添加一個(gè)叫做texture[]的整型變量。它用于保存紋理。后面3行是第14課中的代碼,本課不做改動(dòng)。

GLuint texture[1]; // One Texture Map
GLuint base; // Base Display List For The Font Set
GLfloat rot; // Used To Rotate The Text
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);// Declaration For WndProc


  下面的部分做了一些小改動(dòng)。我打算在這課使用wingdings字體來(lái)顯示一個(gè)海盜旗(骷髏頭和十字骨頭)的標(biāo)志。如果你想顯示文字的話,就不用改動(dòng)第14課中的代碼了,也可以選擇另一種字體。

  有些人想知道如何使用wingdings字體,這也是我不用標(biāo)準(zhǔn)字體的一個(gè)原因。wingdings是一種符號(hào)字體,使用它時(shí)需要做一些改動(dòng)。告訴Windows使用wingdings字體并不太簡(jiǎn)單。如果你把字體的名字改為wingdings,你會(huì)注意到字體其實(shí)并沒(méi)有選到。你必須告訴Windows這種字體是一種符號(hào)字體而不是一種標(biāo)準(zhǔn)字符字體。后面會(huì)繼續(xù)解釋。

GLvoid BuildFont(GLvoid) // Build Our Bitmap Font
{
    GLYPHMETRICSFLOAT gmf[256]; // Address Buffer For Font Storage
    HFONT font; // Windows Font ID

    base = glGenLists(256); // Storage For 256 Characters

    font = CreateFont( -12, // Height Of Font
                                    0, // Width Of Font
                                    0, // Angle Of Escapement
                                    0, // Orientation Angle
                                    FW_BOLD, // Font Weight
                                    FALSE, // Italic
                                    FALSE, // Underline
                                    FALSE, // Strikeout

這就是有魔力的那一行!不使用第14課中的ANSI_CHARSET,我們將使用SYMBOL_CHARSET。這會(huì)告訴Windows我們創(chuàng)建的字體并不是由標(biāo)準(zhǔn)字符組成的典型字體。所謂符號(hào)字體通常是由一些小圖片(符號(hào))組成的。如果你忘了改變這行,wingdings,webdings以及你想用的其它符號(hào)字體就不會(huì)工作。

                                    SYMBOL_CHARSET, // Character Set Identifier

下面幾行沒(méi)有變化。

                                    OUT_TT_PRECIS, // Output Precision
                                    CLIP_DEFAULT_PRECIS, // Clipping Precision
                                    ANTIALIASED_QUALITY, // Output Quality
                                    FF_DONTCARE|DEFAULT_PITCH, // Family And Pitch

既然我們已經(jīng)選擇了符號(hào)字符集標(biāo)識(shí)符,我們就可以選擇wingdings字體了!

                                    "Wingdings"); // Font Name

剩下幾行代碼沒(méi)有變化

    SelectObject(hDC, font); //Selects The Font We Created

    wglUseFontOutlines( hDC, // Select The Current DC
                                        0, // Starting Character
                                        255, // Number Of Display Lists To Build
                                        base, // Starting Display Lists

我們?cè)试S有更多的誤差,這意味著GL不會(huì)嚴(yán)格的遵守字體的輪廓線。如果你把誤差設(shè)置為0.0f,你就會(huì)發(fā)現(xiàn)嚴(yán)格地在曲面上貼圖存在一些問(wèn)題。但是如果你允許一定的誤差,很多問(wèn)題都可以避免。

                                        0.1f, // Deviation From The True Outlines

下面三行代碼還是相同的。

                                        0.2f, // Font Thickness In The Z Direction
                                        WGL_FONT_POLYGONS, // Use Polygons, Not Lines
                                        gmf); // Address Of Buffer To Recieve Data
}

在ReSizeGLScene()函數(shù)之前,我們要加上下面一段代碼來(lái)讀取紋理。你可能會(huì)認(rèn)得這些前幾課中的代碼。我們創(chuàng)建一個(gè)保存位圖的地方,讀取位圖,告訴Windows生成一個(gè)紋理,并把它保存在texture[0]中。

我們創(chuàng)建一種細(xì)化紋理(mipmapped texture),這樣會(huì)看起來(lái)好些。紋理的名字叫做lights.bmp。

AUX_RGBImageRec *LoadBMP(char *Filename) // Loads A Bitmap Image
{
    FILE *File=NULL; // File Handle

    if (!Filename) // Make Sure A Filename Was Given
    {
        return NULL; // If Not Return NULL
    }

    File=fopen(Filename,"r"); // Check To See If The File Exists

    if (File) // Does The File Exist?
    {
        fclose(File); // Close The Handle
        return auxDIBImageLoad(Filename);// Load The Bitmap And Return A Pointer
    }
    return NULL; // If Load Failed Return NULL
}

int LoadGLTextures() // Load Bitmaps And Convert To Textures
{
    int Status=FALSE; // Status Indicator

    AUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texture

    memset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULL

    if (TextureImage[0]=LoadBMP("Data/Lights.bmp")) // Load the Bitmap
    {
        Status=TRUE; // Set The Status To TRUE

        glGenTextures(1, &texture[0]); // Create The Texture

        // Build Linear Mipmapped Texture

        glBindTexture(GL_TEXTURE_2D, texture[0]);
        gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);

下面四行代碼將為我們繪制在屏幕上的任何物體自動(dòng)生成紋理坐標(biāo)。函數(shù)glTexGen非常強(qiáng)大,而且復(fù)雜,如果要完全講清楚它的數(shù)學(xué)原理需要再寫一篇教程。不過(guò),你只要知道GL_S和GL_T是紋理坐標(biāo)就可以了。默認(rèn)狀態(tài)下,它被設(shè)置為提取物體此刻在屏幕上的x坐標(biāo)和y坐標(biāo),并把它們轉(zhuǎn)換為頂點(diǎn)坐標(biāo)。你會(huì)發(fā)現(xiàn)到物體在z平面沒(méi)有紋理,只顯示一些斑紋。正面和反面都被賦予了紋理,這些都是由glTexGen函數(shù)產(chǎn)生的。(X(GL_S)用于從左到右映射紋理,Y(GL_T)用于從上到下映射紋理。

GL_TEXTURE_GEN_MODE允許我們選擇我們想在S和T紋理坐標(biāo)上使用的紋理映射模式。你有3種選擇:

GL_EYE_LINEAR - 紋理會(huì)固定在屏幕上。它永遠(yuǎn)不會(huì)移動(dòng)。物體將被賦予處于它通過(guò)的地區(qū)的那一塊紋理。

GL_OBJECT_LINEAR - 這種就是我們使用的模式。紋理被固定于在屏幕上運(yùn)動(dòng)的物體上。
GL_SPHERE_MAP - 每個(gè)人都喜歡。創(chuàng)建一種有金屬質(zhì)感的物體。

需要注意的是我省略了很多代碼。我們還需要設(shè)置GL_OBJECT_PLANE,但是,默認(rèn)參數(shù)就是我們想要的參數(shù)。如果你想了解更多,那就買一本好書,或者查閱MSDN。

        // Texturing Contour Anchored To The Object

        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

        // Texturing Contour Anchored To The Object

        glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
        glEnable(GL_TEXTURE_GEN_S);
        glEnable(GL_TEXTURE_GEN_T);
    }

    if (TextureImage[0]) // If Texture Exists
    {
        if (TextureImage[0]->data) // If Texture Image Exists
        {
            free(TextureImage[0]->data); // Free The Texture Image Memory
        }
        free(TextureImage[0]); // Free The Image Structure
    }
    return Status; // Return The Status
}


在InitGL()的最后有幾行新代碼。BuildFont()被放到了讀取紋理的代碼之后。glEnable(GL_COLOR_MATERIAL) 這行被刪掉了,如果你想使用glColor3f(r,g,b)來(lái)改變紋理的顏色,那么就把glEnable(GL_COLOR_MATERIAL)這行重新加到這部分代碼中。

    int InitGL(GLvoid) // All Setup For OpenGL Goes Here
    {
        if (!LoadGLTextures()) // Jump To Texture Loading Routine
        {
            return FALSE; // If Texture Didn't Load Return FALSE
        }
        BuildFont(); // Build The Font

        glShadeModel(GL_SMOOTH); // Enable Smooth Shading
        glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
        glClearDepth(1.0f); // Depth Buffer Setup
        glEnable(GL_DEPTH_TEST); // Enables Depth Testing
        glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
        glEnable(GL_LIGHT0); // Quick And Dirty Lighting (Assumes Light0 Is Set Up)
        glEnable(GL_LIGHTING); // Enable Lighting
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations

啟動(dòng)2D紋理映射,并選擇第一個(gè)紋理。這樣就把第一個(gè)紋理映射到我們繪制在屏幕上的3D物體上了。如果你想加入更多的操作,可以按自己的意愿啟動(dòng)或禁用紋理映射。

        glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
        glBindTexture(GL_TEXTURE_2D, texture[0]); // Select The Texture
        return TRUE; // Initialization Went OK

重置大小的代碼沒(méi)有變化,但DrawGLScene這部分代碼有變化。

    int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
        glLoadIdentity(); // Reset The View

這里是第一處變動(dòng)。我們打算使用COS和SIN讓物體繞著屏幕旋轉(zhuǎn)而不是把它固定在屏幕中間。我們將把物體向屏幕里移動(dòng)3個(gè)單位。在x軸,我們將移動(dòng)范圍限制在-1.1到+1.1之間。我們使用rot變量來(lái)控制左右移動(dòng)。我們把上下移動(dòng)的范圍限制在+0.8到-0.8之間。同樣使用rot變量來(lái)控制上下移動(dòng)(最好充分利用你的變量)。

        Position The Texture
        glTranslatef(1.1f*float(cos(rot/16.0f)),0.8f*float(sin(rot/20.0f)),-3.0f);

下面做常規(guī)的旋轉(zhuǎn)。這會(huì)使符號(hào)在X,Y和Z軸旋轉(zhuǎn)。

        glRotatef(rot,1.0f,0.0f,0.0f); // Rotate On The X Axis
        glRotatef(rot*1.2f,0.0f,1.0f,0.0f); // Rotate On The Y Axis
        glRotatef(rot*1.4f,0.0f,0.0f,1.0f); // Rotate On The Z Axis

我們將物體相對(duì)觀察點(diǎn)向左向下移動(dòng)一點(diǎn),以便于把符號(hào)定位于每個(gè)軸的中心。否則,當(dāng)我們旋轉(zhuǎn)它的時(shí)候,看起來(lái)就不像是在圍繞它自己的中心在旋轉(zhuǎn)。-0.35只是一個(gè)能讓符號(hào)正確顯示的數(shù)。我也試過(guò)一些其它數(shù),因?yàn)槲也恢肋@種字體的寬度是多少,可以適情況作出調(diào)整。我不知道為什么這種字體沒(méi)有一個(gè)中心。

        glTranslatef(-0.35f,-0.35f,0.1f); // Center On X, Y, Z Axis

最后,我們繪制海盜旗的符號(hào),然后增加rot變量,從而使這個(gè)符號(hào)在屏幕中旋轉(zhuǎn)和移動(dòng)。如果你不知道我是如何從字母‘N’中得到海盜旗符號(hào)的,那就打開(kāi)Microsoft Word或是寫字板。在字體下拉菜單中選擇Wingdings字體。輸入大寫字母‘N’,就會(huì)顯示出海盜旗符號(hào)了。

        glPrint("N"); // Draw A Skull And Crossbones Symbol
        rot+=0.1f; // Increase The Rotation Variable
        return TRUE; // Keep Going
    }

最后要做的事就是在KillGLWindow()的最后添加KillFont()函數(shù),如下所示。添加這行代碼很重要。它將在我們退出程序之前做清理工作。

    if (!UnregisterClass("OpenGL",hInstance)) // Are We Able To Unregister Class
    {
        MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
        hInstance=NULL; // Set hInstance To NULL
    }
    KillFont();

  盡管我沒(méi)有講的細(xì)致入微,但我想你應(yīng)該很好的理解了如何讓OpenGL為你生成紋理坐標(biāo)。在給你的字體或者是同類物體賦予紋理映射時(shí),應(yīng)該沒(méi)有問(wèn)題了,而且只需要改變兩行代碼,你就可以啟用球體映射了,它的效果簡(jiǎn)直酷斃了!

posted on 2006-01-20 00:22 zmj 閱讀(803) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   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>
            合欧美一区二区三区| 一区二区三区成人精品| 嫩草成人www欧美| 久久久久久精| 欧美中文在线视频| 午夜日韩视频| 午夜在线视频一区二区区别| 亚洲一区二区三区免费在线观看| 亚洲精品在线视频| 亚洲免费成人| 一区二区三区欧美在线| 亚洲一本视频| 午夜精品久久久久影视| 欧美在线播放一区| 久久午夜羞羞影院免费观看| 久久综合999| 欧美成人a视频| 亚洲黄色在线观看| 久久视频在线免费观看| 欧美成人午夜视频| 欧美国产精品v| 亚洲激情在线观看视频免费| 日韩午夜精品视频| 亚洲欧美高清| 久久精品毛片| 欧美3dxxxxhd| 欧美日韩一二三区| 国产目拍亚洲精品99久久精品 | 中国亚洲黄色| 亚洲欧美视频在线| 久久久国产成人精品| 蜜臀久久99精品久久久画质超高清| 欧美大片第1页| 一区在线视频| 欧美日韩亚洲成人| 国产欧美日韩另类视频免费观看| 国产一区二区精品久久99| 在线日韩中文字幕| 在线视频欧美日韩精品| 欧美亚洲免费| 欧美高清免费| 亚洲一区日本| 老司机精品视频一区二区三区| 欧美日韩大片| 国产午夜久久久久| 日韩视频久久| 久久国产欧美| 亚洲欧洲日本国产| 性欧美在线看片a免费观看| 久久成人在线| 欧美日韩在线播放三区四区| 国产综合精品一区| 一区二区三区四区五区在线 | 亚洲久久成人| 欧美伊人影院| 欧美日韩精品在线播放| 极品尤物av久久免费看 | 久热精品视频在线| 国产精品久久久久久久久久久久久| 国产一区二区你懂的| 99国产精品久久久久久久久久| 久久成人人人人精品欧| 亚洲精品激情| 久久久久久电影| 91久久中文字幕| 欧美中文字幕在线| 欧美韩日精品| 西西裸体人体做爰大胆久久久| 欧美极品一区| 在线成人亚洲| 久久国产精品免费一区| 91久久国产综合久久| 欧美在线视频免费| 国产精品美女主播| 夜夜嗨av一区二区三区中文字幕 | 欧美性大战久久久久久久蜜臀| 在线观看免费视频综合| 午夜视频一区二区| 亚洲精品资源美女情侣酒店| 久久综合亚州| 国产一区在线视频| 午夜视频在线观看一区二区| 99精品视频免费在线观看| 免费视频一区| 在线观看福利一区| 久久久亚洲影院你懂的| 亚洲综合精品一区二区| 欧美日韩天堂| 一本一道久久综合狠狠老精东影业| 男女av一区三区二区色多| 欧美亚洲在线| 国产欧美日韩一区| 欧美久久视频| 欧美精品一区二区三区在线播放 | 欧美午夜一区二区福利视频| 亚洲精品一区二区在线观看| 欧美r片在线| 久久婷婷av| 国产色综合网| 欧美一区二区三区啪啪| 亚洲午夜影视影院在线观看| 国产精品jvid在线观看蜜臀 | 欧美风情在线观看| 亚洲黑丝一区二区| 欧美国产日韩一区| 免费日韩av片| 99re成人精品视频| 久久精品一区中文字幕| 久久精品中文| 欧美大胆成人| 国产精品久久久久久久久久久久久久| 国产日韩精品一区| 亚洲成色777777在线观看影院| 亚洲乱码国产乱码精品精| 亚洲视频免费观看| 久久精品视频亚洲| 亚洲福利视频专区| 欧美激情第一页xxx| 在线性视频日韩欧美| 美女性感视频久久久| 国语对白精品一区二区| 欧美一区日本一区韩国一区| 亚洲免费在线电影| 国产综合一区二区| 欧美成人高清| 欧美高清视频www夜色资源网| 日韩亚洲在线| 亚洲一区二区三区在线| 国产一区视频网站| 欧美激情麻豆| 欧美日韩1区2区| 午夜精品视频在线观看| 欧美在线视频二区| 亚洲人成毛片在线播放| av成人手机在线| 国产精品一二一区| 久久免费视频观看| 欧美激情一二三区| 香蕉免费一区二区三区在线观看 | 毛片av中文字幕一区二区| 每日更新成人在线视频| 亚洲少妇自拍| 欧美一区免费视频| 亚洲精品综合久久中文字幕| 亚洲影视中文字幕| 亚洲第一在线视频| 一区二区三区四区国产精品| 欧美gay视频激情| 一区二区三区日韩欧美| 黄色精品一区二区| 一本大道av伊人久久综合| 国产一区二区| 亚洲九九九在线观看| 韩国视频理论视频久久| 日韩视频一区二区三区在线播放| 国产精品在线看| 亚洲国产精品久久久久婷婷老年 | 一区二区三区免费看| 欧美一级理论性理论a| 亚洲精品视频在线观看网站| 亚洲欧美一区二区在线观看| 亚洲日本久久| 欧美在线啊v| 中文在线资源观看网站视频免费不卡 | 亚洲作爱视频| 亚洲福利免费| 亚洲欧美自拍偷拍| 99精品欧美一区二区三区综合在线| 午夜精品免费视频| 一本色道久久综合亚洲精品小说 | 狠狠色狠狠色综合日日91app| 99视频超级精品| 亚洲欧美日韩天堂一区二区| 欧美日韩亚洲一区二区三区四区| 免费成人在线观看视频| 国产精品性做久久久久久| 91久久在线播放| 精品99一区二区三区| 亚洲伊人色欲综合网| 亚洲精选91| 久热爱精品视频线路一| 久久人人爽国产| 国产精品一卡二卡| 一本综合久久| 亚洲精品色婷婷福利天堂| 久久九九电影| 久久精品动漫| 国产精品久久一区二区三区| 亚洲精品乱码久久久久久按摩观| 1024成人| 久久精品亚洲乱码伦伦中文| 欧美中文字幕在线播放| 国产精品外国| 在线视频精品一| 国产精品99久久久久久久vr| 欧美大片免费观看| 欧美激情免费观看| 亚洲国产精品t66y| 久久嫩草精品久久久久| 久久综合九色|