首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

OpenGL 基礎教程 (三):點、線、多邊形繪製樣式精通

     編輯:關於C語言

OpenGL 基礎教程 (三):點、線、多邊形繪製樣式精通

點樣式控制

void glPointSize(GLfloat size); // 設置點大小 (像素),默認 1.0,必須 > 0
// 實際最大值受實現限制,可用 glGetFloatv(GL_POINT_SIZE_RANGE, range) 查詢

示例:繪製 5 像素大小的點:

glPointSize(5.0f);
glBegin(GL_POINTS);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.5f, 0.5f);
glEnd();

線樣式控制

線寬

void glLineWidth(GLfloat width); // 默認 1.0,用法同 glPointSize

虛線模式

glEnable(GL_LINE_STIPPLE);        // 啟用虛線
glLineStipple(GLint factor, GLushort pattern); // 設置模式
// pattern: 16位掩碼,從最低位(LSB)開始,1=實線,0=空白
// factor: 每個位重複的像素數
glBegin(GL_LINES);
    glVertex2f(0.0f, 0.0f);
    glVertex2f(0.5f, 0.5f);
glEnd();
glDisable(GL_LINE_STIPPLE);       // 關閉虛線

模式解讀示例:pattern = 0x3F07 (二進制 0011 1111 0000 0111),從 LSB 讀:

  • factor=1:3像素實線 → 5像素空白 → 6像素實線 → 2像素空白 (循環)。
  • factor=2:6實 → 10空 → 12實 → 4空。

默認 pattern=0xFFFF, factor=1 (實線)。

多邊形樣式控制 (核心內容)

1. 雙面繪製模式

多邊形有正反兩面,可分別設置模式:

glPolygonMode(GL_FRONT, GL_FILL);       // 正面填充 (默認)
glPolygonMode(GL_BACK, GL_LINE);        // 反面線框
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // 兩面均只畫頂點

正面定義:默認頂點按逆時針 (CCW) 順序指定的面為正面。可用 glFrontFace(GL_CW) 改為順時針。

2. 面剔除

提升性能:不繪製背向攝像機的面。

glEnable(GL_CULL_FACE);                 // 啟用剔除
glCullFace(GL_BACK);                    // 剔除反面 (默認)
// glCullFace(GL_FRONT);                // 剔除正面
// glCullFace(GL_FRONT_AND_BACK);       // 剔除兩面 (只剩點/線)

注意:剔除僅影響多邊形 (GL_POLYGON, GL_TRIANGLES 等),不影響點/線。

3. 鏤空模式

類似虛線,用 32x32 位圖模式填充多邊形:

glEnable(GL_POLYGON_STIPPLE);           // 啟用鏤空
GLubyte mask[128] = { ... };            // 128字節 = 32x32 位圖
glPolygonStipple(mask);                 // 設置模式
glRectf(-0.5f, -0.5f, 0.0f, 0.0f);      // 繪製鏤空矩形
glDisable(GL_POLYGON_STIPPLE);          // 關閉
glRectf(0.0f, 0.0f, 0.5f, 0.5f);        // 普通矩形

位圖生成技巧:用畫圖工具建 32x32 像素 BMP,讀取像素數據轉為 mask 數組 (或直接用工具生成十六進制數組)。

完整示例:雙面模式 + 面剔除 + 鏤空演示

void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    
    // 設置正面填充,反面線框
    glFrontFace(GL_CCW); // 逆時針為正面
    glPolygonMode(GL_FRONT, GL_FILL);
    glPolygonMode(GL_BACK, GL_LINE);
    
    // 左下:逆時針正方形 (正面朝向觀察者,顯示填充)
    glBegin(GL_POLYGON);
        glVertex2f(-0.5f, -0.5f);
        glVertex2f(0.0f, -0.5f);
        glVertex2f(0.0f, 0.0f);
        glVertex2f(-0.5f, 0.0f);
    glEnd();
    
    // 右上:順時針正方形 (反面朝向觀察者,顯示線框)
    glBegin(GL_POLYGON);
        glVertex2f(0.0f, 0.0f);
        glVertex2f(0.0f, 0.5f);
        glVertex2f(0.5f, 0.5f);
        glVertex2f(0.5f, 0.0f);
    glEnd();
    
    // 鏤空演示 (需先準備 mask 數組)
    glEnable(GL_POLYGON_STIPPLE);
    glPolygonStipple(fly_mask); // 包含"麻煩的開始,不建議使用"等文字位圖
    glRectf(-0.5f, -0.5f, 0.0f, 0.0f);
    glDisable(GL_POLYGON_STIPPLE);
    
    glFlush();
}

核心心法

  • 狀態機模型:glEnable/Disable 開關狀態,gl*Stipple 設置參數,繪製調用時生效。
  • 正反面由頂點順序決定,建模時保持一致性 (統一 CCW) 避免剔除錯誤。
  • 數據外部化:複雜模式 (如鏤空位圖) 存文件/資源,運行時加載,分離代碼與數據。
  • 現代 OpenGL (Core Profile) 已棄用上述固定管線函數,需用 Shader 實現同樣效果 (片段著色器 discard、Geometry Shader 等)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved