open gl 3d觀察

       淺淺地學習到open gl 的3d觀察,對一些函數還不是理解的很透徹,但是還是用心地做了個小實驗——三維觀察小程序。

       只要是用了心的程序,我就想好好在csdn整理下,或許日後會有用也說不定。這也是一種點滴的積累吧。

       先看看what文件提供的數據格式吧(太多行,有11610個頂點座標,23216個三角形)

       

       

// 參考http://www.cnblogs.com/lizhengjin/archive/2010/09/23/1833580.html
// 參考http://blog.csdn.net/zzyoucan/article/details/8521823
#include<stdio.h>
#include "glut.h"
int countOfVertex;
int countOfTriangle;     

GLfloat** vertex_list;                        
GLint**   index_list;                             

// 從what數據文件讀取數據
void readData()
{
	int i;
	FILE *fp;
	if((fp=fopen("what.txt","r"))==NULL)
	{
		printf("Can't open the file!\n"); 
		exit(0);
	}
	fscanf(fp,"%d",&countOfVertex);
	printf("%d\t",countOfVertex);
	fscanf(fp,"%d",&countOfTriangle);
	printf("%d",countOfTriangle);
	 
    // 接下來是難點,爲2個2維數組動態申請內存空間
	///////////////////////////////////////////////////////////////////////////////////////////
    vertex_list = new GLfloat*[countOfVertex];
	for (i=0;i<countOfVertex;i++)
	{
		vertex_list[i]=new GLfloat[3];
	}
	
	index_list = new GLint*[countOfTriangle];
	for (i=0;i<countOfTriangle;i++)
	{
		index_list[i]=new GLint[4];
	}
    ////////////////////////////////////////////////////////////////////////////////////////////

	for(i=0;i<countOfVertex;i++)
	{
		fscanf(fp,"%f%f%f",&vertex_list[i][0],&vertex_list[i][1],&vertex_list[i][2]);
	}

	for(i=0;i<countOfTriangle;i++)
	{
		fscanf(fp,"%d%d%d%d",&index_list[i][0],&index_list[i][1],&index_list[i][2],&index_list[i][3]);
	}
    fclose(fp);
}

static GLfloat theta[] = {0.0,0.0,0.0};    //  看來初始的旋轉角度爲0            
static GLint axis = 2;
static GLdouble viewer[]= {0.0, 0.0, 5.0}; /* initial viewer location */ 

void display(void)
{
	int i, j;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);

	glLoadIdentity();

	gluLookAt(viewer[0],viewer[1],viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

	glRotatef(theta[0], 1.0, 0.0, 0.0);
	glRotatef(theta[1], 0.0, 1.0, 0.0);
	glRotatef(theta[2], 0.0, 0.0, 1.0);
	
//	glBegin(GL_TRIANGLES);                     
	for(i=0; i<countOfTriangle; i++) 
	{
		glBegin(GL_LINE_LOOP);
		for(j=1; j<=3; j++)  
		{
			glVertex3fv(vertex_list[index_list[i][j]]);
		}
		glEnd();
	}
    glFlush();
	glutSwapBuffers();
}

void mouse(int btn, int state, int x, int y)          // 鼠標左中右鍵改變的都是旋轉角度 
{
	if(btn==GLUT_LEFT_BUTTON && state == GLUT_DOWN) axis = 0;
	if(btn==GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) axis = 1;
	if(btn==GLUT_RIGHT_BUTTON && state == GLUT_DOWN) axis = 2;
	theta[axis] += 2.0;
	if( theta[axis] > 360.0 ) theta[axis] -= 360.0;
	display();
}

void keys(unsigned char key, int x, int y)
{
/* Use x, X, y, Y, z, and Z keys to move viewer */   // 鍵盤的xyz 改變眼睛的位置  viewer[0] viewer[1] viewer[2] 用在gluLookAt

   if(key == 'x') viewer[0]-= 1.0;
   if(key == 'X') viewer[0]+= 1.0;
   if(key == 'y') viewer[1]-= 1.0;
   if(key == 'Y') viewer[1]+= 1.0;
   if(key == 'z') viewer[2]-= 1.0;
   if(key == 'Z') viewer[2]+= 1.0;
   display();
}

void myReshape(int w, int h)
{
 glViewport(0, 0, w, h);
/* Use a perspective view */
 glMatrixMode(GL_PROJECTION); 
 glLoadIdentity();
 if(w<=h) glFrustum(-0.2, 0.2, -0.2 * (GLfloat) h/ (GLfloat) w,               // 此時h/w >1   -0.2 ~ 0.2  
    0.2* (GLfloat) h / (GLfloat) w, 2.0, 40.0);
 else glFrustum(-0.2, 0.2, -0.2 * (GLfloat) w/ (GLfloat) h,                       // 此時w/h >1
    0.2* (GLfloat) w / (GLfloat) h, 2.0, 20.0);

/* Or we can use gluPerspective */
 // gluPerspective(20.0, w/h, -0.1, 0.1);

 glMatrixMode(GL_MODELVIEW);        // 設置回模型矩陣
}

void
main(int argc, char **argv)
{
         readData();
	 glutInit(&argc, argv);
	 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	 glutInitWindowSize(500, 500);
	 glutCreateWindow("牛");

 	 glEnable(GL_DEPTH_TEST);

	 glutReshapeFunc(myReshape);

	 glutDisplayFunc(display);
	 glutMouseFunc(mouse);
	 glutKeyboardFunc(keys);

	 glutMainLoop();

	 // 這裏釋放這2個二維數組,其實不釋放也行,因爲進程結束了,自動回收內存
	 int i;
	 for(i=0;i<countOfVertex;i++)
	 {
		 delete  [] vertex_list[i];
	 }
	 delete [] vertex_list;

	 for(i=0;i<countOfTriangle;i++)
	 {
		 delete  [] index_list[i];
	 }
	 delete [] index_list;

}
效果:


       

 // 收穫:1.直面了C++必須學會的動態創建多維數組

                2.fscanf函數的使用,讀取文件數據

                3.glFrustum函數前2個參數,調準近裁剪面的寬度越小如-0.2~0.2 =0.4 就很小,這樣顯示的物體就大,如果改爲-2~2,=4那麼會小的多。             

                4.glBegin(GL_LINE_LOOP);函數不等於glBegin(GL_LINES)。後者會以兩輛相連,顯然不適合用於畫一個獨立的三角形。

                 5.發現改變glFrustum函數的倒數第二個參數zNear居然會改變物體顯示大小,視錐變了?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章