Skip to main content

Featured

Build docker image from multiple build contexts

Build docker image from multiple build contexts Building a docker image requires specifying a source of truth to include in the image from a local directory or a remote git repository. In the previous version, the docker BuildKit allows users to specify the build context from a single source of truth only. However, the engineers may need to have the context from different locations based on the type of files. For instance, icons, images or other resources that are not included in the same package, including the resource from other docker images. Fortunately, the Docker Buildx toolkit supports multiple build context flag for Docker 1.4. Let's learn how to use this new feature. The following list is a shortcut for jumping into a specific topic handy. What version of Docker is this tutorial targeting? How to specify the version of Dockerfile frontend? Ho

[OpenGL]使用OpenGL顯示文字 - 標準英文字

此處參考了Nehe的L13來進行實作。

繪製的部份一樣是在DrawScene裡面處理,但需新增方便用來顯示文字的glPrint()。
建立OpenGL繪圖視窗的方式可以參考[MFC]使用Picture Control來當做DrawScene

建立流程如下:
1.先建立可以存放字集的變數於header檔內。
 class COpenGLDrawer :    public CWnd  
 {  
 ....  
 //================ Data member ==================  
 //------------------ Set Font Head ---------------  
 //BOOK:Draw Font  
         GLuint m_gluiBaseDisplayList;       //For the font set  
                                             //base will hold the number of the first display list we create. Each character requires it's own display list.   
                                             //The character 'A' is 65 in the display list, 'B' is 66, 'C' is 67, etc. So 'A' would be stored in display list base+65.   
 //------------------ Set Font Foot ---------------  
 ....  
 };  

2.接下來的是產生字表的glBuildFont()。
Header:
 class COpenGLDrawer :    public CWnd  
 {  
 ....  
  protected:  
   GLvoid glBuidFont(GLvoid);  
 ....  
 };  

CPP:
 GLvoid COpenGLDrawer::glBuidFont(GLvoid)  
 {  
     HFONT hFont;  
     HFONT holdFont;    //stores the previously used font.   
                        //SelectObject will return the font (or pen, or filler, or whatever GDI objects) that was previously set when it switches to the new font.  
                        //The way that GDI works is such that the use of the return value of SelectObject is not very apparent.   
                        //At first glance it looks as if the code is selecting the new font and returning a pointer and storing it within oldFont.   
     this->m_gluiBaseDisplayList = glGenLists(CHAR_LIST_NUM);                //Storage for 96 characters (NEW)  
     hFont = ::CreateFont(        FONT_HIEGHT,    //Height of Font (NEW)  
                                                  //By putting a minus, we're telling windows to find us a font based on the CHARACTER height.   
                                                  //If we use a positive number we match the font based on the CELL height.   
                                            0,    //Width of Font  
                                            0,    //Angle of Escapement  
                                            0,    //Orientation Angle  
                                    FW_NORMAL,    //Font Weight  
                                                  //You can put a number from 0 - 1000 or you can use one of the predefined values.   
                                                  //FW_DONTCARE is 0, FW_NORMAL is 400, FW_BOLD is 700 and FW_BLACK is 900.   
                                                  //There are alot more predefined values, but those 4 give some good variety. The higher the value, the thicker the font (more bold).   
                                        FALSE,    //Italic  
                                        FALSE,    //Underline  
                                        FALSE,    //Strikeout  
                                 ANSI_CHARSET,    //Character Set Identifier  
                                                  //Character set Identifier describes the type of Character set you wish to use.   
                                                  //There are too many types to explain.   
                                                  //CHINESEBIG5_CHARSET, GREEK_CHARSET, RUSSIAN_CHARSET, DEFAULT_CHARSET, etc.   
                                                  //ANSI is the one I use, although DEFAULT would probably work just as well.  
                                                  //If you're interested in using a font such as Webdings or Wingdings,   
                                                  //        you need to use SYMBOL_CHARSET instead of ANSI_CHARSET.   
                                OUT_TT_PRECIS,    //Output Precision  
                                                  //It tells Windows what type of character set to use if there is more than one type available.   
                                                  //OUT_TT_PRECIS tells Windows that if there is more than one type of font to choose from with the same name,   
                                                  //        select the TRUETYPE version of the font. Truetype fonts always look better, especially when you make them large.   
                                                  //You can also use OUT_TT_ONLY_PRECIS, which ALWAYS trys to use a TRUETYPE Font.   
                          CLIP_DEFAULT_PRECIS,    //Clipping Precision  
                                                  //Clipping Precision is the type of clipping to do on the font if it goes outside the clipping region.   
                                                  //Not much to say about this, just leave it set to default.   
                          ANTIALIASED_QUALITY,    //Output Quality  
                                                  //Output Quality is very important. You can have PROOF, DRAFT, NONANTIALIASED, DEFAULT or ANTIALIASED.   
                                                  //We all know that ANTIALIASED fonts look good :)   
                                                  //Antialiasing a font is the same effect you get when you turn on font smoothing in Windows. It makes everything look less jagged.   
                    FF_DONTCARE|DEFAULT_PITCH,    //Family and Pitch  
                                                  //Next we have the Family and Pitch settings.   
                                                  //For pitch you can have DEFAULT_PITCH, FIXED_PITCH and VARIABLE_PITCH,   
                                                  //    and for family you can have FF_DECORATIVE, FF_MODERN, FF_ROMAN, FF_SCRIPT, FF_SWISS, FF_DONTCARE.   
                                                  //Play around with them to find out what they do. I just set them both to default.   
                            DISPLAY_FONT_TYPE     // Font Name  
                                                  //Can replace the value with the font you would rather use.  
             );  
     holdFont = (HFONT)::SelectObject(this->m_hdc, hFont);          //Selects the Font we want.  
     wglUseFontBitmaps(this->m_hdc, CHAR_LIST_START_POINT, CHAR_LIST_NUM, this->m_gluiBaseDisplayList);        //Build 96 Characters Starting at Character 32.  
     ::DeleteObject(hFont);                                                                                    //Delete the Font  
 }  

3.當然也是需要釋放記憶體用的glKillFont。呼叫時機就看使用情況,目前是在Desctructor時進行。
Header:
 class COpenGLDrawer :    public CWnd  
 {  
 ....  
  protected:  
   GLvoid glKillFont(GLvoid);  
 ....  
 };  

CPP:
GLvoid COpenGLDrawer::glKillFont(GLvoid)
{
glDeleteLists(this->m_gluiBaseDisplayList, CHAR_LIST_NUM); //Delete all 96 Characeters
}

4.用來繪製文字的glPrint(),作者為了方便使用,就包裝成printf()模式。
Header:
 class COpenGLDrawer :    public CWnd  
 {  
 ....  
  protected:  
   GLvoid glPrint(const char* szFormat, ...);  
 ....  
 };  

CPP:
 GLvoid COpenGLDrawer::glPrint(const char* szFormat, ...)  
 {  
     char szText[256];        //Holds Our String  
     va_list argList;            //Pointer to List of arguments  
     if ( szFormat == NULL ) {  
         return; };  
     va_start(argList, szFormat);  
     vsprintf(szText, szFormat, argList);  
     va_end(argList);  
     //We then push the GL_LIST_BIT, this prevents glListBase from affecting any other display lists we may be using in our program.   
     //The command glListBase(base-32) is a little hard to explain. Say we draw the letter 'A', it's represented by the number 65.   
     //Without glListBase(base-32) OpenGL wouldn't know where to find this letter.   
     //It would look for it at display list 65, but if base was equal to 1000, 'A' would actually be stored at display list 1065.   
     //So by setting a base starting point, OpenGL knows where to get the proper display list from. The reason we subtract 32 is because we never made the first 32 display lists.   
     //We skipped them. So we have to let OpenGL know this by subtracting 32 from the base value. I hope that makes sense.   
     glPushAttrib(GL_LIST_BIT);                                                                            //Pushes the Display List Bits  
     glListBase( this->m_gluiBaseDisplayList-CHAR_LIST_START_POINT );        //Sets the base Character to 32  
     //Now that OpenGL knows where the Letters are located, we can tell it to write the text to the screen. glCallLists is a very interesting command.   
     //It's capable of putting more than one display list on the screen at a time.  
     //The line below does the following. First it tells OpenGL we're going to be displaying lists to the screen. strlen(text) finds out how many letters we're going to send to the screen.   
     //Next it needs to know what the largest list number were sending to it is going to be. We're not sending any more than 255 characters.   
     //The lists parameter is treated as an array of unsigned bytes, each in the range 0 through 255. Finally we tell it what to display by passing text (pointer to our string).  
     //In case you're wondering why the letters don't pile on top of eachother. Each display list for each character knows where the right side of the letter is.   
     //After the letter is drawn, OpenGL translates to the right side of the drawn letter.   
     //The next letter or object drawn will be drawn starting at the last location GL translated to, which is to the right of the last letter.  
     //Finally we pop the GL_LIST_BIT setting GL back to how it was before we set our base setting using glListBase(base-32).   
     glCallLists(strlen(szText), GL_UNSIGNED_BYTE, szText);                                //Draw the display list text  
     glPopAttrib();                                                                                                    //Pops the Display List Bits  
 }  

5.使用時機就是在DrawScene()裡面處理就可以了,先畫線或是先顯示文字部分,目前測試是都可以。
 void COpenGLDrawer::glDrawScene(void)  
 {  
 //**************** Draw Grid Head *******************  
     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);            //Set polygon rasterization mode  
     glBegin(GL_QUADS);                                                                    //Start to draw squares  
     for ( unsigned int i = 0 ; i < this->m_vcdsGrid.size() ; i++ )  
     {  
     //3D  
         //glVertex3f(this->m_vcdsGrid[i].LB.x, this->m_vcdsGrid[i].LB.y, this->m_vcdsGrid[i].LB.z);  
         //glVertex3f(this->m_vcdsGrid[i].RB.x, this->m_vcdsGrid[i].RB.y, this->m_vcdsGrid[i].RB.z);  
         //glVertex3f(this->m_vcdsGrid[i].RT.x, this->m_vcdsGrid[i].RT.y, this->m_vcdsGrid[i].RT.z);  
         //glVertex3f(this->m_vcdsGrid[i].LT.x, this->m_vcdsGrid[i].LT.y, this->m_vcdsGrid[i].LT.z);  
     //2D          
         glVertex2f(this->m_vcdsGrid[i].LB.x, this->m_vcdsGrid[i].LB.y);  
         glVertex2f(this->m_vcdsGrid[i].RB.x, this->m_vcdsGrid[i].RB.y);  
         glVertex2f(this->m_vcdsGrid[i].RT.x, this->m_vcdsGrid[i].RT.y);  
         glVertex2f(this->m_vcdsGrid[i].LT.x, this->m_vcdsGrid[i].LT.y);  
         if ( !this->m_vcdsGrid4AStar[i].IsWarkable ) {  
             this->m_vcdsGrid4DrawBlocking.push_back(m_vcdsGrid4AStar[i]);    };  
     }    //End of for ( unsigned int i = 0 ; i < this->m_vcpGrid.size() ; i++ )  
     glEnd();  
 //**************** Draw Grid Foot *******************  
 //**************** Draw Font Head *******************  
     CString cstrDisplay;  
     SIZE nLen;  
     for ( unsigned int i = 0 ; i < this->m_vcdsGrid4AStar.size() ; i++ )  
     {  
 //Pulsing colors based on text position  
         glColor3f( 1.0f, 1.0f, 1.0f );        //White  
 //Position the text on the screen  
         glRasterPos2f( (this->m_vcdsGrid4AStar[i].cdsGridInfo.LB.x + 0.1f), (this->m_vcdsGrid4AStar[i].cdsGridInfo.LB.y + 0.1f) );        //set to center  
 //Print GL text to the screen  
         this->glPrint("%d", this->m_vcdsGrid4AStar[i].nCostedAP);  
         glRasterPos2f( this->m_vcdsGrid4AStar[i].cdsGridInfo.LT.x + 0.1f, this->m_vcdsGrid4AStar[i].cdsGridInfo.LT.y - 0.2f);  
         this->glPrint("%d", this->m_vcdsGrid4AStar[i].nTotalCostAP);  
         cstrDisplay.Format("%d", this->m_vcdsGrid4AStar[i].nRequiredAP2Target+100);  
         ::GetTextExtentPoint32(this->m_hdc, cstrDisplay, cstrDisplay.GetLength(), &nLen);  
         glRasterPos2f( this->m_vcdsGrid4AStar[i].cdsGridInfo.RB.x - 0.03f*nLen.cx, this->m_vcdsGrid4AStar[i].cdsGridInfo.RB.y + 0.1f);  
         this->glPrint("%d", this->m_vcdsGrid4AStar[i].nRequiredAP2Target+100);  
     }    //End of for ( unsigned int i = 0 ; i < this->m_vcdsGrid.size() ; i++ )  
 //**************** Draw Font Foot *******************  
 }  


此處輸入的是在每個Cell內的左上、左下以及右下塞入各一個數字,結果如下圖:

Comments

  1. 可以給我程式原始檔參考嗎?

    ReplyDelete
  2. @哈密頓
    哈密頓您好:
    請問需要哪一段的程式碼?
    這邊貼出的部分,是針對顯示文字處理的部分。

    至於OpenGL繪圖部分,那是屬於另外的函式。

    不知您是要哪一部份?

    ReplyDelete

Post a Comment

Popular Posts