2022/5/3 第十一周
主題 : glm 模型
1. 安裝freeglut 和 OpenCV2.1(+咒語)
2. 開GLUT專案+把鋼彈模型的模式檔放入
(1)把下載的gundam.zip的模式檔 data裡的檔案 放到 桌面/freeglut/bin/data/裡面
(2) 把week09_opencv的範例複製到week10_gundam使用
#include <opencv/highgui.h>
int main()
{
IplImage * img = cvLoadImage("data/Diffuse.jpg");
cvShowImage("week11", img);
cvWaitKey(0);
}
3. 實作glm模型: 把茶壺貼上Gundam的貼圖
(1)複製上禮拜的myTexture 、 display 跟 main
#include <GL/glut.h>
#include <opencv/highgui.h>
#include <opencv/cv.h>
int myTexture(char * filename)
{
IplImage * img = cvLoadImage(filename);
cvCvtColor(img,img, CV_BGR2RGB);
glEnable(GL_TEXTURE_2D);
GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
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;
}
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( GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week11 gundam");
glutDisplayFunc(display);
myTexture("data/Diffuse.jpg"); ///這邊要修改!!
glutMainLoop();
}
(1) 在jsyeh.org/3dcg10 下載 source.zip ,將source.zip裡面的glm.h、glm.c(改成glm.cpp) 和 transformation.c 放到week11_gundam裡(當main.cpp的鄰居)
(2) 在week11_gundam專案的左邊workspace的week11_gundam那裡按右鍵Add file...,選glm.cpp
(3)加上讀入gundam模型的程式碼
#include <GL/glut.h>
#include <opencv/highgui.h>
#include <opencv/cv.h>
#include "glm.h"
GLMmodel * pmodel = NULL; ///空指標
int myTexture(char * filename)
{
IplImage * img = cvLoadImage(filename);
cvCvtColor(img,img, CV_BGR2RGB);
glEnable(GL_TEXTURE_2D);
GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
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;
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
///glutSolidTeapot(0.3);
if( pmodel == NULL){ ///如果是空指標(第5行),表示模型沒裝好,所以要讀模型(只會跑一次,裝好了就不會再裝一次)
pmodel = glmReadOBJ("data/Gundam.obj"); ///讀模型
glmUnitize( pmodel ); ///換算成Unit單位大小(-1...+1)
glmFacetNormals( pmodel ); ///重新計算模型的"面"的法向量
glmVertexNormals( pmodel , 90 ); ///重新計算模型的"頂點"的法向量
}
glmDraw( pmodel, GLM_TEXTURE ); ///有模型後,把pmodel畫出來(面、貼圖) ///25~31行其實是從transformation.c裡抄來的!
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week11 gundam");
glutDisplayFunc(display);
myTexture("data/Diffuse.jpg"); ///這邊要修改!!
glutMainLoop();
}
(4) 模型貼圖怪怪的......將圖上下顛倒
---> 去小畫家把data/Diffuse.jpg 垂直翻轉,再將week11_gundam跑一次
(5) 模型好像被壓扁了......因為還沒將3D的前後深度測試
---> 在main函式裡加上glEnable(GL_DEPTH_TEST);
(6) 讓模型轉起來!!
#include <GL/glut.h>
#include <opencv/highgui.h>
#include <opencv/cv.h>
#include "glm.h"
GLMmodel * pmodel = NULL;///空指標
int myTexture(char * filename)
{
IplImage * img = cvLoadImage(filename);
cvCvtColor(img,img, CV_BGR2RGB);
glEnable(GL_TEXTURE_2D);
GLuint id;
glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
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;
}
float angle=0;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
///glutSolidTeapot(0.3);
if( pmodel == NULL){///如果是空指標(第5行),表示模型沒裝好,所以要讀模型(只會跑一次)
pmodel = glmReadOBJ("data/Gundam.obj"); ///讀模型
glmUnitize( pmodel ); ///換算成Unit單位大小(-1...+1)
glmFacetNormals( pmodel ); ///重新計算模型的"面"的法向量
glmVertexNormals( pmodel , 90 ); ///重新計算模型的"頂點"的法向量
}
glPushMatrix();
glRotatef(angle, 0,1,0);
glmDraw( pmodel, GLM_TEXTURE );///有模型後,把pmodel畫出來(面、貼圖)
glPopMatrix();
glutSwapBuffers();
angle +=1;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week11 gundam");
glutIdleFunc(display);
glutDisplayFunc(display);
myTexture("data/Diffuse.jpg"); ///這邊要修改!!
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}
5. 如何使用Maya匯出3D模型檔(OBJ) + 切模型(分成頭、身體、腳...)
----> google搜尋: maya obj 檔案
ex頭: 將body.mtl body.obj放入freeglut/bin/data裡 ,在改讀模型那行-->data/body.obj 就可以讀出模型了!
###如何讀出一個人體模型: 先用maya將頭、身體、腳(可以拆成更細部的關節)各做成一個obj檔,在將所有的obj檔案放入freeglut/bin/data裡,就可以讀入各個關節了
6. 對特定軸做旋轉(轉手的部分)
#include <GL/glut.h>
void hand(){ ///畫手
glColor3f(0,1,0);
glutSolidTeapot(0.2);
}
void body(){ ///畫身體
glColor3f(1,1,0);
glutSolidTeapot(0.3);
}
float angle=0;
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
body();
glPushMatrix();
glTranslatef(0.5,0.2,0);
glRotatef(angle, 0,0,1);
glTranslatef(0.3,0,0);
hand();
glPopMatrix();
glutSwapBuffers();
angle +=1;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week11_TRT");
glutIdleFunc(display);
glutDisplayFunc(display);
glutMainLoop();
}







沒有留言:
張貼留言