日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OpenGL三维模型+常见错误

發布時間:2023/12/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenGL三维模型+常见错误 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

項目文件資源鏈接//download.csdn.net/download/H200102/12101806

一、OpenGL導入三維模型

1.期末的圖形學作業要做三維機器人,要求:可以轉換視角;光照;機器人可以移動(局部運動);
2.查看資料后發現,發現大部分都是采用畫出機器人各部分(幾何圖形,正方形長方形圓柱體)后組裝的方式,我采用導入現有模型(三維模型)的方式,這樣的模型比我自己畫出的模型更美觀和好看,
3.之后再給機器人貼紋理,渲染環境,設置光照等,設置鍵盤響應函數移動機器人,使機器人身體運動,旋轉觀察機器人
4.總結:最終實現了能夠立體觀察機器人,機器人能夠運動(左右上下移動),旋轉,放大縮小機器人。
?? 但沒有實現機器人的局部運動,比如只是機器人的手動或者腳動,機器人的紋理也沒有貼(紋理部分自己沒有學習,有空有心情再學,專門挑了一個不需要貼紋理的機器人)

二、實現步驟
方式一:使用deep exploration軟件
1.先尋找一個obj模型,使用deep exploration將模型轉換成cpp文件
2.將obj模型的cpp文件導入VS中,或者將cpp文件內容粘貼在VS中的項目中
3.deep exploration將模型轉換成的cpp文件,是使用顯示列表將模型畫出來,顯示列表存儲了模型的頂點數據,光照材質等內容
4.在cpp文件中添加如下代碼內容

#include <gl/glaux.h> #include <gl/glu.h> #include <GL/glut.h> #include<iostream> #include<string> #include<iomanip> using namespace std; #include "math.h" #include <stdio.h>int flag = 1; double front_Point_x, front_Point_y, front_Point_z; double pos_Up[3], pos_Down[3], pos_Motion[3]; double viewmatrix[16], modelviewmatrix[16]; #define GLUT_MIDDLE_UP_BUTTON 0x0003 #define GLUT_MIDDLE_DOWN_BUTTON 0x0004 float PI = 3.141592654; int listnum;//導入變量 GLfloat xangle = 0.0; GLfloat yangle = 0.0; GLfloat oDistance = 5.0; int cacheX = 0; int cacheY = 0; int xSpeed = 1; int ySpeed = 1; BOOL light = true; // 光源的開/關 BOOL lp = true; // L鍵按下了么? GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; //環境光參數 GLfloat LightDiffuse[] = { 0.5f, 0.5f, 0.5f, 1.0f }; // 漫射光參數,不要全設置為0 GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f }; // 光源位置static GLfloat angle = 0.0; static GLfloat movex = 0.0; static GLfloat movey = 0.0; static GLfloat len = 15.0; static GLint x = 0.0, y = 0.0, z = 0.0;/* 該部分是cpp文件內容 *//*繪制*/ void motion(int x, int y) //鼠標響應事件 {if (x > cacheX){yangle = yangle - xSpeed;}if (x < cacheX){yangle = yangle + xSpeed;}if (y > cacheY){xangle = xangle + ySpeed;}if (y < cacheY){xangle = xangle - ySpeed;}glutPostRedisplay();cacheX = x;cacheY = y; } /* void setView() //設置觀察角度 {glRotatef(10, 1.0, 0.0, 0.0); //設置opengl中繪制實體的自轉方式,即物體如何旋轉glRotatef(22, 0.0, 1.0, 0.0);glTranslatef(-20.5, -10.0, -55.0);/*沿X軸正方向平移x個單位(x是有符號數)沿Y軸正方向平移y個單位(y是有符號數)沿Z軸正方向平移z個單位(z是有符號數)glGetDoublev(GL_MODELVIEW_MATRIX, viewmatrix); } */ void SetRC() //設置渲染 {glEnable(GL_LINE_SMOOTH);glEnable(GL_BLEND);glShadeModel(GL_SMOOTH);/*設置著色模式,解決實心圖形內部空間顏色填充,平滑著色*/glFrontFace(GL_CW);glEnable(GL_LINE_SMOOTH);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);/*設置顏色混合,透明度疊加*/glHint(GL_LINE_SMOOTH, GL_NICEST); /* 設置反面為邊緣繪制方式*/glEnable(GL_DEPTH_TEST);//glPolygonMode(GL_BACK, GL_FILL); // 設置模型背面為實體//glPolygonMode(GL_BACK, GL_LINE);/*glPolygonMode(GL_FRONT, GL_FILL); // 設置正面為填充方式glPolygonMode(GL_BACK, GL_LINE); // 設置反面為邊緣繪制方式glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); // 設置兩面均為頂點繪制方式*/glEnable(GL_COLOR_MATERIAL); }void renderWorld() //模擬場景 {glFrontFace(GL_CCW); //逆時針表示正面//glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 設置多邊形的正面和背面為實體,填充//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // 設置多邊形的正面和背面為線性,不填充float oXhudu = PI / (180 / xangle); //沿著X軸旋轉的角度float oYhudu = PI / (180 / yangle); //沿著Y軸旋轉的角度//設置場景坐標GLfloat btm = oDistance * cos(oXhudu);GLfloat vpY = oDistance * sin(oXhudu);GLfloat vpX = btm * sin(oYhudu);GLfloat vpZ = btm * cos(oYhudu);if (fabs(xangle) < 90.0){gluLookAt(vpX, vpY, vpZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); //觀察}else{if (fabs(xangle) >= 270.0){if (fabs(xangle) >= 360.0){xangle = 0.0;}gluLookAt(vpX, vpY, vpZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);}else{gluLookAt(vpX, vpY, vpZ, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);}}if (fabs(yangle) >= 360.0){yangle = 0;}//繪制場景坐標軸/*glLineWidth(1);glBegin(GL_LINES);glColor3f(1.0, 0.0, 0.0);glVertex3f(0.0, 0.0, 0.0);glVertex3f(200, 0, 0);glColor3f(0.0, 1.0, 0.0);glVertex3f(0.0, 0.0, 0.0);glVertex3f(0.0, 200, 0.0);glColor3f(0.0, 0.0, 1.0);glVertex3f(0.0, 0.0, 0.0);glVertex3f(0.0, 0.0, 200.0);glEnd();*/glColor3f(0.863, 0.863, 0.863); //機器人的顏色glEnable(GL_LIGHTING); //啟用顏色混合glEnable(GL_LIGHT0);glGetDoublev(GL_MODELVIEW_MATRIX, modelviewmatrix); //坐標變換glCallList(listnum); // 執行顯示列表 }//向上平移 void moveup() {movey += 2.0;if (movey > 100.0)movey = 0.0;glutPostRedisplay(); } //向下平移 void movedown() {movey -= 2.0;if (movey < -100.0)movey = 0.0;glutPostRedisplay(); } //向左平移 void moveleft() {movex -= 2.0;if (movex < -100.0)movex = 0.0;glutPostRedisplay(); } //向右平移 void moveright() {movex += 2.0;if (movex > 100.0)movex = 0.0;glutPostRedisplay(); } //放大 void zoom() {len += 0.02;if (len > 20.0)len = 10.0;glutPostRedisplay(); /*glutPostRedisplay 標記當前窗口需要重新繪制*/ } //收縮 void shrink() {len -= 0.02;if (len < 1.0)len = 10.0;glutPostRedisplay(); } //沿x軸旋轉 void rotatex() {z = 0.0;x = 1.0;y = 0.0;angle += 1.0;if (angle >= 360.0)angle = 0.0;glutPostRedisplay(); } //沿y軸旋轉 void rotatey() {z = 0.0;y = 1.0;x = 0.0;angle += 5.0;if (angle >= 360.0)angle = 0.0;glutPostRedisplay(); } //沿z軸旋轉 void rotatez() {z = 1.0;x = 0.0;y = 0.0;angle += 1.0;if (angle >= 360.0)angle = 0.0;glutPostRedisplay(); } //沿xy軸旋轉 void rotatexy() {z = 0.0;y = 1.0;x = 1.0;angle += 1.0;if (angle >= 360.0)angle = 0.0;glutPostRedisplay(); } //沿yz軸旋轉 void rotateyz() {z = 1.0;y = 1.0;x = 0.0;angle += 1.0;if (angle >= 360.0)angle = 0.0;glutPostRedisplay(); } //沿xz軸旋轉 void rotatexz() {z = 1.0;y = 0.0;x = 1.0;angle += 1.0;if (angle >= 360.0)angle = 0.0;glutPostRedisplay(); } //沿xyz軸旋轉 void rotatexyz() {z = 1.0;y = 1.0;x = 1.0;angle += 1.0;if (angle >= 360.0)angle = 0.0;glutPostRedisplay(); }void changeLine() {glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // 設置多邊形的正面和背面為線性,不填充} void changemodle() {glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // 設置多邊形的正面和背面為實體,填充}//定義鍵位 void specialKeyFunc(int key, int x, int y) {switch (key){case GLUT_KEY_UP:moveup();break;case GLUT_KEY_DOWN:movedown();break;case GLUT_KEY_LEFT:moveleft();break;case GLUT_KEY_RIGHT:moveright();break;case GLUT_KEY_F1:zoom();break;case GLUT_KEY_F2:shrink();break;case GLUT_KEY_F3:rotatex(); //沿x軸旋轉break;case GLUT_KEY_F4:rotatey();break;case GLUT_KEY_F5:rotatez();break;case GLUT_KEY_F6:rotatexy();break;case GLUT_KEY_F7:rotateyz();break;case GLUT_KEY_F8:rotatexz();break;case GLUT_KEY_F9:rotatexyz();break;case GLUT_KEY_F10:changeLine();break;case GLUT_KEY_F11:changemodle();break;default:break;} }static void init() {glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //設置窗體顏色}void Display(void) {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glColor3f(1.0, 1.0, 0.0);glPushMatrix();glTranslatef(movex, movey, 0.0); //平移函數glScalef(9 * len, 9 * len, len); //縮放函數glRotatef(angle, x, y, z); //繪制實體的自轉方式,即物體如何旋轉renderWorld();glPopMatrix();glutSwapBuffers(); //該函數的功能是交換兩個緩沖區指針,實現雙緩沖 }void Reshape(int w, int h) //重新繪制場景 {GLfloat nRange = 100.0f;glViewport(0, 0, w, h);//表示這個視口矩形的寬度和高度,根據窗口的實時變化重繪窗口。glMatrixMode(GL_PROJECTION);/*glMatrixMode()函數的參數,這個函數其實就是對接下來要做什么進行一下聲明,也就是在要做下一步之前告訴計算機我要對“什么”進行操作了,這個“什么”在glMatrixMode的“()”里的選項(參數)有3種模式: GL_PROJECTION 投影, GL_MODELVIEW 模型視圖, GL_TEXTURE 紋理.*/glLoadIdentity();if (w <= h) //建立裁剪區域(左右下上近遠){glOrtho(-nRange, nRange, -nRange * h / w, nRange*h / w, -100, 100);/*glOrtho(left, right, bottom, top, near, far), left表示視景體左面的坐標,right表示右面的坐標,bottom表示下面的,top表示上面的。*/}else{glOrtho(-nRange * w / h, nRange*w / h, -nRange, nRange, -100, 100);}glMatrixMode(GL_MODELVIEW);glLoadIdentity(); }void mouse(int btn, int state, int x, int y) {if (btn == GLUT_RIGHT_BUTTON){if (state == GLUT_DOWN){if (light){glDisable(GL_LIGHT1); // 啟用光源light = !light;}else{glEnable(GL_LIGHT1);light = !light;}}}glutPostRedisplay();//重新加載}//菜單 void menu() {cout << "-------------------------菜單-----------------------------------" << endl;cout << "----------------按住方向鍵左即向左運動------------------------" << endl;cout << "----------------按住方向鍵右即向右運動------------------------" << endl;cout << "----------------按住方向鍵上即向上運動------------------------" << endl;cout << "----------------按住方向鍵下即向下運動------------------------" << endl;cout << "----------------按住鼠標拖動即旋轉----------------------------" << endl;cout << "----------------按住F1放大------------------------------------" << endl;cout << "----------------按住F2縮小------------------------------------" << endl;cout << "----------------按住F3繞x軸旋轉------------------------------" << endl;cout << "----------------按住F4繞y軸旋轉------------------------------" << endl;cout << "----------------按住F5繞z軸旋轉------------------------------" << endl;cout << "----------------按住F6繞xy軸旋轉------------------------------" << endl;cout << "----------------按住F7繞yz軸旋轉------------------------------" << endl;cout << "----------------按住F8繞xz軸旋轉------------------------------" << endl;cout << "----------------按住F9繞xyz軸旋轉------------------------------" << endl;cout << "----------------按住F10后點擊模型,變為線框圖-----------------" << endl;cout << "----------------按住F11后點擊模型,填充模型--------------------" << endl;}int main(int argc, char *argv[]) //主函數 {glutInit(&argc, argv);menu(); //打印控制臺菜單glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);//定義窗口的顯示模式,使用RGB染色的模式,雙緩沖模式glutInitWindowPosition(10, 10);glutInitWindowSize(800, 800);glutCreateWindow("丑不拉幾的機器人");glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 設置環境光glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 設置漫射光glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); // 光源位置glEnable(GL_LIGHT1); // 啟用光源init();listnum = Gen3DObjectList(); //glutDisplayFunc(&Display);glutReshapeFunc(&Reshape);glutSpecialFunc(specialKeyFunc); //鍵盤響應SetRC();glutMouseFunc(mouse);glutMotionFunc(&motion);glutMainLoop();return 0; }

5.cpp文件部分內容:

struct sample_MATERIAL {GLfloat ambient[3]; //環境光顏色GLfloat diffuse[3]; //漫反射光GLfloat specular[3]; //鏡面反射光GLfloat emission[3]; //自體發光的物體GLfloat alpha; //描述物體在給定像素的不透明度GLfloat phExp;int texture; //紋理 }; //材質結構體變量 static sample_MATERIAL materials[13] = { }; //存儲所有頂點坐標 static GLfloat vertices[35125][3] = { }; 存儲所有法向量 static GLfloat normals[40950][3] = { }; 存儲所有紋理坐標 static GLfloat textures[10110][2] = { }; //材質索引,用于獲取材質模型 static int material_ref[510][2] = { }; //使用OpenGL命令無定義(三角)面的顏色 void MyMaterial(GLenum mode, GLfloat * f, GLfloat alpha) { }//根據模式選擇材質結構體的相應變量 void SelectMaterial(int i) { }; //顯示列表 GLint Gen3DObjectList() {int i;int j;GLint lid = glGenLists(1); //1個空顯示列表,生成顯示類表int mcount = 0;int mindex = 0;glNewList(lid, GL_COMPILE); //創建顯示列表glBegin(GL_TRIANGLES); //開始繪圖//每3分坐標相連接for (i = 0; i < sizeof(face_indicies) / sizeof(face_indicies[0]); i++){if (!mcount){SelectMaterial(material_ref[mindex][0]);mcount = material_ref[mindex][1];mindex++;}mcount--;for (j = 0; j < 3; j++){//載入紋理、法線、頂點向量int vi = face_indicies[i][j];int ni = face_indicies[i][j + 3];//Normal indexint ti = face_indicies[i][j + 6];//Texture indexglNormal3f(normals[ni][0], normals[ni][1], normals[ni][2]);glTexCoord2f(textures[ti][0], textures[ti][1]);glVertex3f(vertices[vi][0], vertices[vi][1], vertices[vi][2]);}}glEnd(); //繪圖結束glEndList(); //結束顯示列表return lid; };

6.運行結果
1)控制臺菜單

2)機器人

3)機器人

4)按F10后點擊模型,轉換為線框圖,按F11后點擊模型,轉換為實心形態

方式二:使用view 3DS軟件
1.使用VIEW3DS軟件將三維模型的MAX文件轉換為gl文件和.h文件
2.其他內容和使用deep exploration軟件一樣,只是需要將gl文件和.h文件放在VS項目下,并在cpp文件中添加頭文件#include"Robot.h" /*Robot.h文件是模型轉換后的文件*/
在主函數中載入模型部分代碼:
Robot robot; listnum = GL3DS_initialize_Robot(); //載入Robot

3.運行效果:

三、錯誤提示

1.VS2017利用fopen和fscanf讀取文件時出現以下錯誤信息:
C4996 ‘fopen’: This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

解決辦法:
項目——屬性——C/C++——預處理器——預處理器定義——右側下拉框中“編輯”——在第一個編輯框中添加_CRT_SECURE_NO_WARNINGS——大功告成


2.在vs中char類型的實參與LPCWSTR類型的形參類型不兼容怎么解決;
“char *” 類型的實參與 “LPCTSTR” 類型的形參不兼容

解決辦法:
在 項目 - 屬性 - 常規 中把字符集修改為“未設置”即可。

能將參數 1 從“const char [11]”轉換為“LPCWSTR”

解決方法:
選中項目,然后點擊屬性——>配置屬性——>常規——>項目默認值——>字符集,選為“使用多字節字符集"


3.復制粘貼代碼時,可能出現錯誤,但找不到原因,比如提示main函數錯誤,
可以換一下粘貼的順序,先粘貼main函數和頭文件部分,在粘貼函數其他部分

總結

以上是生活随笔為你收集整理的OpenGL三维模型+常见错误的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。