--- tags: c tutor --- # OpenGL範例 網址: https://hackmd.io/@jsyeh/opengl 相關筆記 - [2021電腦圖學](https://hackmd.io/@jsyeh/2021graphics) - [2022電腦圖學](https://hackmd.io/@jsyeh/2022graphics) - [OpenGL範例](https://hackmd.io/@jsyeh/opengl) ## 最簡單的 10 行範例 ```cpp= #include <GL/glut.h> void display() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glutSolidTeapot( 0.3 ); glutSwapBuffers(); } int main( int argc, char ** argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GL_DOUBLE | GL_DEPTH ); glutCreateWindow("Week01"); glutDisplayFunc(display); glutMainLoop(); } ``` ## 色彩 - 設定背景色彩 `glClearColor(r,g,b,a)` - 純清背景`glClear(GL_COLOR_BUFFER_BIT)` - `glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)` - 設定色彩 `glColor3f(r,g,b)` ```cpp= #include <GL/glut.h> void display() { //背景色名詞 Clear的Color,用來清背景的色彩 glClearColor(1,0,0,1);//R,G,B,A 其中 A 目前模式不會用到 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); //動詞 Clear 清背景 glColor3f(1,1,0); //黃色的 glutSolidTeapot( 0.3 ); //茶壼 glutSwapBuffers(); } int main( int argc, char ** argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GL_DOUBLE | GL_DEPTH ); glutCreateWindow("Week01"); glutDisplayFunc(display); glutMainLoop(); } ``` ## 點線面色彩 ```cpp= #include <GL/glut.h> void display() { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glBegin(GL_POLYGON); glColor3f(1,0,0); glVertex2f(+1,-1); glColor3f(0,1,0); glVertex2f(-1,-1); glColor3f(0,0,1); glVertex2f(+1, 0); glEnd(); glutSwapBuffers(); } int main( int argc, char ** argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GL_DOUBLE | GL_DEPTH ); glutCreateWindow("Week01"); glutDisplayFunc(display); glutMainLoop(); } ``` ## 移動 `glTranslatef(x,y,z);` 要配合 `glPushMatrix()` `glPopMatrix()` 範例:把茶壼移到右上角 ```cpp= //待完成 #include ``` ## 旋轉 `glRotatef(角度, x,y,z);` 要配合 `glPushMatrix()` `glPopMatrix()` 還記得國中理化教過「安培右手定則」嗎? 利用右手座標系統:伸出右手比個「讚!」,就會決定旋轉的方向。需要理解 `旋轉角度`、`旋轉軸` 範例:把茶壼旋轉45度 ```cpp= //待完成 #include <stdio.h> int main() { printf("Hello world\n"); glClear() } ``` ## 滑鼠 mouse 函式 `glutMouseFunc(mouse);` 範例:滑鼠在視窗中點擊時,按按鍵會印出對應數值 ```cpp= ``` ## 滑鼠 motion 函式 `glutMotionFunc(motion);` ## 鍵盤 keyboard 函式 `glutKeyboardFunc(keyboard);` ## 貼圖 Texture [myTexture.cpp](https://gist.github.com/jsyeh/5ed01210559721ec71b659b3ffed2dd7) in gist.github.com/jsyeh ```cpp= #include <opencv/highgui.h> ///使用 OpenCV 2.1 比較簡單, 只要用 High GUI 即可 #include <opencv/cv.h> #include <GL/glut.h> int myTexture(char * filename) { IplImage * img = cvLoadImage(filename); ///OpenCV讀圖 cvCvtColor(img,img, CV_BGR2RGB); ///OpenCV轉色彩 (需要cv.h) glEnable(GL_TEXTURE_2D); ///1. 開啟貼圖功能 GLuint id; ///準備一個 unsigned int 整數, 叫 貼圖ID glGenTextures(1, &id); /// 產生Generate 貼圖ID glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖T, 就重覆貼圖 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖S, 就重覆貼圖 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /// 貼圖參數, 放大時的內插, 用最近點 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); /// 貼圖參數, 縮小時的內插, 用最近點 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB, GL_UNSIGNED_BYTE, img->imageData); return id; } ``` ## 圓球貼圖 myEarth 使用 gluQuadric() 配合 myTexture ## 打光 Lighting [light_teapot.cpp](https://gist.github.com/jsyeh/dc869b19a47b293f8bd123fedc0259c2) in gist.github.com/jsyeh ## 進階:讀入模型 glm.cpp 讀入 3D 模型 (OBJ 檔) 先從 source.zip 裡面得到 glm.h 及 glm.c(改成glm.cpp,加入專案中),再模仿 transformation.c 裡面讀模型的程式。 下面是隨手寫的,還沒有檢查 ```cpp= #include <GL/glut.h> #include "glm.h" GLMmodel * pmodel = NULL; void draw_model() { if(pmodel==NULL){ pmodel = glmReadOBJ("filename.obj");//with mtl glmUnitize(pmodel);//這行可選擇 glmFacetNormal(pmodel); glmVertexNormal(pmodel); } glmDrawOBJ(pmodel); } ``` ## 進階:搞懂 T-R-T 對特定軸旋轉 ## 進階:搞懂 階層(很多層)轉動