生活随笔
收集整理的這篇文章主要介紹了
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 ;
GLfloat LightAmbient
[ ] = { 0.5f , 0.5f , 0.5f , 1.0f } ;
GLfloat LightDiffuse
[ ] = { 0.5f , 0.5f , 0.5f , 1.0f } ;
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 ;
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 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
) ; glEnable ( GL_COLOR_MATERIAL
) ;
} void renderWorld ( )
{ glFrontFace ( GL_CCW
) ; float oXhudu
= PI
/ ( 180 / xangle
) ; float oYhudu
= PI
/ ( 180 / yangle
) ; 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 ; } 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 ( ) ;
}
void shrink ( )
{ len
- = 0.02 ; if ( len
< 1.0 ) len
= 10.0 ; glutPostRedisplay ( ) ;
}
void rotatex ( )
{ z
= 0.0 ; x
= 1.0 ; y
= 0.0 ; angle
+ = 1.0 ; if ( angle
>= 360.0 ) angle
= 0.0 ; glutPostRedisplay ( ) ;
}
void rotatey ( )
{ z
= 0.0 ; y
= 1.0 ; x
= 0.0 ; angle
+ = 5.0 ; if ( angle
>= 360.0 ) angle
= 0.0 ; glutPostRedisplay ( ) ;
}
void rotatez ( )
{ z
= 1.0 ; x
= 0.0 ; y
= 0.0 ; angle
+ = 1.0 ; if ( angle
>= 360.0 ) angle
= 0.0 ; glutPostRedisplay ( ) ;
}
void rotatexy ( )
{ z
= 0.0 ; y
= 1.0 ; x
= 1.0 ; angle
+ = 1.0 ; if ( angle
>= 360.0 ) angle
= 0.0 ; glutPostRedisplay ( ) ;
}
void rotateyz ( )
{ z
= 1.0 ; y
= 1.0 ; x
= 0.0 ; angle
+ = 1.0 ; if ( angle
>= 360.0 ) angle
= 0.0 ; glutPostRedisplay ( ) ;
}
void rotatexz ( )
{ z
= 1.0 ; y
= 0.0 ; x
= 1.0 ; angle
+ = 1.0 ; if ( angle
>= 360.0 ) angle
= 0.0 ; glutPostRedisplay ( ) ;
}
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 ( ) ; 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
) ; glLoadIdentity ( ) ; if ( w
<= h
) { glOrtho ( - nRange
, nRange
, - nRange
* h
/ w
, nRange
* h
/ w
, - 100 , 100 ) ; } 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
) ; 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 ] = {
} ;
void MyMaterial ( GLenum mode
, GLfloat
* f
, GLfloat alpha
)
{
}
void SelectMaterial ( int i
)
{
} ;
GLint
Gen3DObjectList ( )
{ int i
; int j
; GLint lid
= glGenLists ( 1 ) ; int mcount
= 0 ; int mindex
= 0 ; glNewList ( lid
, GL_COMPILE
) ; glBegin ( GL_TRIANGLES
) ; 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 ] ; int ti
= face_indicies
[ i
] [ j
+ 6 ] ; glNormal3f ( 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三维模型+常见错误 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。