Week16 閻覃的上課筆記
貼圖
在老師的幫助下我實現了貼兩張不同的圖片。
貼圖的時候需要OpenCV,相關步驟在之前的部落格有提到過。
首先建立一個Image Class
Image.h
1//2// Created by Ethan on 2017/6/12.3//4///for cvLoadImage()5///for cvCvtColor()6789101112131415161718class Image {19public:20 Image(char *filename);2122 GLUquadric *quad;23 GLuint id;24 IplImage *img;25};262728//INC_05052553_WEEK15_IMAGE_HImage.cpp
1//2// Created by Ethan on 2017/6/12.3//4567Image::Image(char *filename) {8 img = cvLoadImage(filename); ///OpenCV讀圖9 cvCvtColor(img, img, CV_BGR2RGB); ///OpenCV轉色彩 (需要cv.h)10 quad = gluNewQuadric();11 glGenTextures(1, &id); /// 產生Generate 貼圖ID12 glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID13 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖T, 就重覆貼圖14 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); /// 貼圖參數, 超過包裝的範圖S, 就重覆貼圖15 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /// 貼圖參數, 放大時的內插, 用最近點16 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); /// 貼圖參數, 縮小時的內插, 用最近點17 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height, 0, GL_RGB, GL_UNSIGNED_BYTE, img->imageData);1819}在程式碼中,可以新建幾個貼圖
1Image *background;2Image *platform;3background = new Image("background.jpg");4platform = new Image("platform.jpg");之後就可以結合打光,在Display中貼圖了。
打光控制
有時候,貼圖會很暗,是因為打光的原因,如果將打光禁用就可以維持圖片本來的顏色。
以下程式碼在display函式中:
1 // draw background2 glEnable(GL_TEXTURE_2D);3 glDisable(GL_LIGHTING);4 glBindTexture(GL_TEXTURE_2D, background->id);5 glPushMatrix();6 {7 glTranslatef(0, .5, 0);89 glRotatef(90, 0, 1, 0);10 glRotatef(90, 1, 0, 0);11 gluQuadricTexture(background->quad, 1);12 gluSphere(background->quad, 2, 20, 20);13 }14 glPopMatrix();15 glDisable(GL_TEXTURE_2D);16 glEnable(GL_LIGHTING);17首先啟用貼圖,關閉打光
之後畫出一個有貼圖的圓球
最後禁用貼圖,啟用打光。
切換貼圖
在剛才的程式碼中有一行
1glBindTexture(GL_TEXTURE_2D, background->id);這是說將接下來的貼圖切換到background的id上,所以就會貼background.jpg
比如我還想貼一個平台的圖片,那麼就可以繼續加程式碼:
1 // platform2 glEnable(GL_TEXTURE_2D);3 glBindTexture(GL_TEXTURE_2D, platform->id);4 glPushMatrix();5 {6 glBegin(GL_POLYGON);7 {8 const float size =1;9 const float y = -0.54f;10 glNormal3f(0,1,0);11 glTexCoord2f(0, 0);12 glVertex3f(-size, y, +size);13 glTexCoord2f(1, 0);14 glVertex3f(+size, y, +size);15 glTexCoord2f(1, 1);16 glVertex3f(+size, y, -size);17 glTexCoord2f(0, 1);18 glVertex3f(-size, y, -size);19 }20 glEnd();2122 }23 glPopMatrix();24 glDisable(GL_TEXTURE_2D);25這裡遇到了幾個難點,因為畫了一個平台,所以法向量如果不調整會出錯,光照會變得很昏暗,所以應該將法向量手動調整一下,才可以顯示出貼圖,否則就是一片漆黑。如果關閉打光也可以正常顯示,不過我這裡是要求開啟打光的,所以要設置法向量。
解決音畫不同步問題(卡拍子)
需要include以下檔案
123開始播放時記錄開始播放的系統時間
startTime = std::chrono::high_resolution_clock::now();
在timer函式中算出時間差
x
1std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();2std::chrono::duration<double, std::milli> time_span = t2 - director->startTime;3float newTime = (float) (BPM * time_span.count() / 30000.0);其中BPM是歌曲的BPM,這個公式是根據我的程式產生的。
我的程式中,一拍(1beat)等於 2frame
用於計算角度等的time可以看作frame的序號
在這裡通過獲取當前系統時間,算出經過了多少時間,再通過BPM(60s中有多少beat)算出當前經過了多少beat,這時就可以換算出當前經過了多少frame,因此直接跳到當前的frame,計算角度就好。
通過這樣計算,無論電腦卡頓還是窗口拖動影響,都不會卡拍子。
沒有留言:
張貼留言