2023年2月22日 星期三

JIA的電腦圖學日誌 Week02

 1

今天的第一個程式,和上週一樣用 CodeBlocks 17.12 新增 GLUT 專案

點 File > New > Project, 選 GLUT Project


點 ... ,選目錄 桌面 , 再加上專案名稱 week02_GLUT_first


下一步選 ... ,選目錄 freeglut

再介紹一次,先複製 freeglut > lib 中的 libfreeglut.a,修改檔名為 libglut32.a (偽裝成glut檔案)



執行小黑, 一樣能看到上週六個旋轉的圖形

但是!這週換我們自己來啦!

先複製10行程式碼

#include <GL/glut.h>
void display()
{
        glutSolidTeapot(0.3);///畫出一個實心的茶壺,它的大小是0.3
glutSwapBuffers();///請GLUT把畫面swap送到顯示的地方
}
int main(int argc, char *argv[])
{ ///上面是特別的main函式,有很多參數
glutInit(&argc, argv);///把GLUT開起來 (GLUT初始化)
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
        ///上面這行是把顯示的模式設定好
glutCreateWindow("GLUT Shapes");///要開視窗
glutDisplayFunc(display);///要顯示的對應函式
glutMainLoop();///最後用main迴圈,壓在最後面
}


執行小黑, 出現了白色的茶壺!


接著做點變化!

glColor3f(r,g,b) 讓我們的圖案上點顏色吧!

例如 glColor3f(1,1,0) 是黃色 , 對應紅、綠、藍 範圍介於 0 - 1 , 開始吧!

#include <GL/glut.h>
void display()
{
glColor3f(1,1,0);///黃色
glutSolidTeapot(0.3);///畫出一個實心的茶壺,它的大小是0.3
glutSwapBuffers();///請GLUT把畫面swap送到顯示的地方
}
int main(int argc, char *argv[])
{ ///上面是特別的main函式,有很多參數
glutInit(&argc, argv);///把GLUT開起來
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);///把顯示的模式設定好
glutCreateWindow("GLUT Shapes");///要開視窗
glutDisplayFunc(display);///要顯示的對應函式
glutMainLoop();///最後用main迴圈,壓在最後面
}


執行小黑, 茶壺變黃色了!


再做一些變化

#include <GL/glut.h>
void display()
{
        glColor3f(0,1,0);///綠色
        glutSolidTeapot(0.5);///畫出一個實心的茶壺,它的大小是0.5
    
glColor3f(1,1,0);///黃色
glutSolidTeapot(0.3);///畫出一個實心的茶壺,它的大小是0.3
glutSwapBuffers();///請GLUT把畫面swap送到顯示的地方
}
int main(int argc, char *argv[])
{ ///上面是特別的main函式,有很多參數
glutInit(&argc, argv);///把GLUT開起來
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);///把顯示的模式設定好
glutCreateWindow("GLUT Shapes");///要開視窗
glutDisplayFunc(display);///要顯示的對應函式
glutMainLoop();///最後用main迴圈,壓在最後面
}


執行小黑, 出現了大的綠茶壺壓在原先的黃茶壺下面!



glBegin(GL_POLYGON) 開始畫出多邊形!

glEnd( ) 結束畫圖形!

glVertex2f( x, y ) 畫頂點!

先參考下面這張圖

我們在畫頂點時,想像一下 x軸和 y軸

舉例三角形的三個頂點就是:( 1, -1)  ( 0, 1)  (-1,-1)


#include <GL/glut.h>
void display()
{
    ///glColor3f(0,1,0);///綠色
///glutSolidTeapot(0.5);///畫出一個實心的茶壺,它的大小是0.5
    glBegin(GL_POLYGON);///開始畫出多邊形
        glVertex2f( 0, 1);///頂點 Vertex
        glVertex2f(-1,-1);///頂點 Vertex
        glVertex2f(+1,-1);///頂點 Vertex
    glEnd();///結束畫

glColor3f(1,1,0);///黃色
glutSolidTeapot(0.3);///畫出一個實心的茶壺,它的大小是0.3
glutSwapBuffers();///請GLUT把畫面swap送到顯示的地方
}
int main(int argc, char *argv[])
{ ///上面是特別的main函式,有很多參數
glutInit(&argc, argv);///把GLUT開起來
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);///把顯示的模式設定好
glutCreateWindow("GLUT Shapes");///要開視窗
glutDisplayFunc(display);///要顯示的對應函式
glutMainLoop();///最後用main迴圈,壓在最後面
}


執行小黑, 綠色三角形背景就出現啦!


那上週的漸層三角形是怎麼做的呢?

結合上面的 glColor3f(r,g,b) 

分別設置了紅色、綠色和藍色的頂點,中間的顏色就會過渡過去啦

#include <GL/glut.h>
void display()
{
    ///glColor3f(0,1,0);///綠色
///glutSolidTeapot(0.5);///畫出一個實心的茶壺,它的大小是0.5
    glBegin(GL_POLYGON);///開始畫出多邊形
        glColor3f(1,0,0);  glVertex2f( 0, 1);///紅色的頂點 Vertex
        glColor3f(0,1,0);  glVertex2f(-1,-1);///綠色的頂點 Vertex
        glColor3f(0,0,1);  glVertex2f(+1,-1);///藍色的頂點 Vertex
    glEnd();///結束畫

glColor3f(1,1,0);///黃色
glutSolidTeapot(0.3);///畫出一個實心的茶壺,它的大小是0.3
glutSwapBuffers();///請GLUT把畫面swap送到顯示的地方
}
int main(int argc, char *argv[])
{ ///上面是特別的main函式,有很多參數
glutInit(&argc, argv);///把GLUT開起來
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);///把顯示的模式設定好
glutCreateWindow("GLUT Shapes");///要開視窗
glutDisplayFunc(display);///要顯示的對應函式
glutMainLoop();///最後用main迴圈,壓在最後面
}


執行小黑, 綠色三角形就變成漸變的三角形啦!



2

今天的第二個程式,和第一個一樣用 CodeBlocks 17.12 新增 GLUT 專案

點 File > New > Project, 選 GLUT Project


點 ... ,選目錄 桌面 , 再加上專案名稱 week02-2_GLUT_many_vertex


因為步驟都一樣, 就不重複說啦, 直接開始囉!

我們現在要來做皮卡丘!

首先如何抓到正確的顏色呢?

先把我們找到的皮卡丘圖片丟入小畫家

將畫布尺寸調整成 200 × 200,為什麼呢?



前面說過想像 x y軸,我們 x軸往右100往左100,y軸向上100 向下100

就形成了 200 × 200 的畫面啦



下一步,用滴管吸取顏色

打開面板查找顏色對應的值,接下來就交給glut吧!

像是 (247,247,247) 變成 (247/255.0,247/255.0,247/255.0)個別除以255.0

glBegin(GL_POLYGON) 開始畫背景吧

因為頂點設在四個角(要按照順序不然會畫亂掉哦)

( 1, 1)往左(-1, 1)往下(-1,-1)往右( 1,-1)跟最早的( 1, 1)相連

背景就被顏色填滿啦

下一步我們畫的是皮卡丘的肚子,選色的方法一樣

但畫點的方式就比較硬了(後面再介紹更快速的方法吧)

我們剛才上面說了畫布是 200 × 200

 移動我們的游標,小畫家的左下角可以看到位置的對應數值

做個運算!口訣:
減一半、除一半、y 變負號

glEnd()壓在結尾

#include <GL/glut.h>
void display()
{
    glColor3f(0);
    ;///開始畫背景
        glVertex2f( 1, 1);
        glVertex2f(-1, 1);
        glVertex2f(-1,-1);
        glVertex2f( 1,-1);
    glEnd();///結束畫

    glColor3f(244/255.0,209/255.0,33/255.0);
    glBegin(GL_POLYGON);///開始畫皮卡丘肚子
        glVertex2f( (45-100)/100.0, -(134-100)/100.0 );
        glVertex2f( (36-100)/100.0, -(171-100)/100.0 );
        glVertex2f( (108-100)/100.0, -(179-100)/100.0 );
        glVertex2f( (104-100)/100.0, -(117-100)/100.0 );
        ///口訣:減一半、除一半、y變負號
    glEnd();///結束畫

glutSwapBuffers();///請GLUT把畫面swap送到顯示的地方
}
int main(int argc, char *argv[])
{ ///上面是特別的main函式,有很多參數
glutInit(&argc, argv);///把GLUT開起來
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);///把顯示的模式設定好
glutCreateWindow("GLUT Shapes");///要開視窗
glutDisplayFunc(display);///要顯示的對應函式
glutMainLoop();///最後用main迴圈,壓在最後面
}


執行小黑, 出現了皮卡丘肚皮(簡單的示範一下,之後再細化)


以下是更改後的版本

自製 myVertex 函式 把 減一半、除一半、y變負號 提出來, 後續只要輸入位置點就好啦

#include <GL/glut.h>
void myVertex(float x, float y)
{
    glVertex2f( (x-100)/100.0, -(y-100)/100.0 );
}
void display()
{
    glColor3f(247/255.0,247/255.0,247/255.0);
    glBegin(GL_POLYGON);///開始畫背景
        glVertex2f( 1, 1);
        glVertex2f(-1, 1);
        glVertex2f(-1,-1);
        glVertex2f( 1,-1);
    glEnd();///結束畫

    glColor3f(244/255.0,209/255.0,33/255.0);
    glBegin(GL_POLYGON);///開始畫皮卡丘肚子
        myVertex(45,134);///glVertex2f( (45-100)/100.0, -(134-100)/100.0 );
        myVertex(36,171);///glVertex2f( (36-100)/100.0, -(171-100)/100.0 );
        myVertex(108,179);///glVertex2f( (108-100)/100.0, -(179-100)/100.0 );
        myVertex(104,117);///glVertex2f( (104-100)/100.0, -(117-100)/100.0 );
        ///口訣:減一半、除一半、y變負號
    glEnd();///結束畫

glutSwapBuffers();///請GLUT把畫面swap送到顯示的地方
}
int main(int argc, char *argv[])
{ ///上面是特別的main函式,有很多參數
glutInit(&argc, argv);///把GLUT開起來
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);///把顯示的模式設定好
glutCreateWindow("GLUT Shapes");///要開視窗
glutDisplayFunc(display);///要顯示的對應函式
glutMainLoop();///最後用main迴圈,壓在最後面
}

👌3

今天的第三個程式, 建立步驟都相同, 專案名稱 week02-3_GLUT_circle_cos_sin

先 include <math.h> 因為 cos sin 要使用

接著自製 myCircle 函式

float a=0;a<2*3.1415926;a+=0.01 畫圓 π 是 180 度, 所以 3.14 需要乘 2 才是完整的圓

glVertex2f( r*cos(a)+x, r*sin(a)+y ) r 是半徑, 決定圓的大小, x 和 y 控制圓的位置上 下 左 右

再給每個圓型配上顏色吧!

#include <GL/glut.h>
#include <math.h> ///cos() 和 sin() 要用
void myCircle(float r, float x, float y)
{
    glBegin(GL_POLYGON);///開始畫圓
       for(float a=0;a<2*3.1415926;a+=0.01){
            glVertex2f( r*cos(a)+x, r*sin(a)+y );
       }
    glEnd();///結束畫

}

void display()
{
    glColor3f(1,0,1); myCircle( 0.6, 0, 0 );///正中間

    glColor3f(1,0,0); myCircle( 0.3, 0.5, 0.5 );///右上角
    glColor3f(0,1,0); myCircle( 0.3,-0.5, 0.5 );///左上角
    glColor3f(1,1,0); myCircle( 0.3,-0.5,-0.5 );///左下角
    glColor3f(0,0,1); myCircle( 0.3, 0.5,-0.5 );///右下角

glutSwapBuffers();///請GLUT把畫面swap送到顯示的地方
}
int main(int argc, char *argv[])
{ ///上面是特別的main函式,有很多參數
glutInit(&argc, argv);///把GLUT開起來
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);///把顯示的模式設定好
glutCreateWindow("GLUT Shapes");///要開視窗
glutDisplayFunc(display);///要顯示的對應函式
glutMainLoop();///最後用main迴圈,壓在最後面
}


執行小黑, 出現了五個位置顏色不相同的圓型!



👋最後


上傳 GitHub 就結束本週的課程啦

💛成果展示

利用頂點、色彩, 畫出你覺得很帥的圖片













沒有留言:

張貼留言