OpenGL學習——glut/ 球體繪製原理,brensenham算法/ 代碼&註釋/ From芃

  • 球體繪製底層代碼實現
    這個看懂有點難度額,我自己都沒仔細研究呢哈哈。
    反正學了沒壞處奧。
    在這裏插入圖片描述
#include <gl/glut.h>
#include<math.h>
#define PI 3.14159265358979323846
#define PI2 6.28318530717958647692

GLsizei width = 600,height = 600;          //球的大小

int uStepsNum = 50,vStepNum = 50;          //線的條數,從一個極點到另外一個極點的條數

class Point                                //點的數據結構
{
public:
    Point(){};
    Point(double a,double b,double c):x(a),y(b),z(c){};
public:
    double x;
    double y;
    double z;                             //xyz三個座標
};
Point getPoint(double u,double v)        //參數座標(u,v)轉換成時機座標(x,y,z)函數
{
    double x = sin(PI*v)*cos(PI2*u);
    double y = sin(PI*v)*sin(PI2*u);
    double z = cos(PI*v);
    return Point(x,y,z);               //球面參數座標的轉換公式
}
void drawWire()                         //繪製球面
{
    double ustep = 1/(double)uStepsNum, vstep = 1/(double)vStepNum; //離散化處理,設置增量大小
    double u = 0,v = 0;   //初始化位置,v是球面點與原點的連線與z軸正向的夾角,u表示連線在xy平面的投影與x軸正向的夾角
    //繪製下端三角形組
    for(int i = 0;i<uStepsNum;i++)
    {
        glBegin(GL_LINE_LOOP);              //GL_LINE_LOOP繪製的
        Point a = getPoint(0,0);
        glVertex3d(a.x,a.y,a.z);             //繪製三維空間座標點
        Point b = getPoint(u,vstep);
        glVertex3d(b.x,b.y,b.z);
        Point c = getPoint(u+ustep,vstep);
        glVertex3d(c.x,c.y,c.z);
        u += ustep;
        glEnd();
    }                                        //下端三角形組主要是繪製極點附近的圖形
    //繪製中間四邊形組
    u = 0, v = vstep;
    for(int i=0;i<vStepNum-1;i++)
    {
        for(int j=0;j<uStepsNum;j++)
        {
            glBegin(GL_LINE_LOOP);
            Point a = getPoint(u,v);
            Point b = getPoint(u+ustep,v);
            Point c = getPoint(u+ustep,v+vstep);
            Point d = getPoint(u,v+vstep);
            glVertex3d(a.x,a.y,a.z);
            glVertex3d(b.x,b.y,b.z);
            glVertex3d(c.x,c.y,c.z);
            glVertex3d(d.x,d.y,d.z);
            u += ustep;
            glEnd();
        }
        v += vstep;
    }
    //繪製下端三角形組
    u = 0;
    for(int i=0;i<uStepsNum;i++)
    {
        glBegin(GL_LINE_LOOP);
        Point a = getPoint(0,1);
        Point b = getPoint(u,1-vstep);
        Point c = getPoint(u+ustep,1-vstep);
        glVertex3d(a.x,a.y,a.z);
        glVertex3d(b.x,b.y,b.z);
        glVertex3d(c.x,c.y,c.z);
        glEnd();
    }
}
void init()
{
    glClearColor(0,0,1,1);//使用指定顏色清除顏色緩衝區
    glClearDepth(0.0);//指定深度緩衝區的清除值
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//要清除顏色緩衝以及深度緩衝
    glClearColor(0,1,1,1);
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    GLfloat light_position [ ] = { 1.0f, 1.0f, 1.0f, 0.0f }; //光源位置
    GLfloat light_ambient  [ ] = { 0.2f, 0.2f, 0.2f, 0.2f }; //環境光
    GLfloat light_diffuse  [ ] = { 0.5f, 0.5f, 0.5f, 0.2f };//漫反射光
    GLfloat light_specular [ ] = { 0.5f, 0.5f, 0.5f, 0.2f };//鏡面反射光
    glLightfv(GL_LIGHT0, GL_POSITION,  light_position); //創建指定的光源,light可以是GL_LIGHT0、GL_LIGHT1,pname定義的是光源的屬性,它指定了一個命名參數。params表示表示pname屬性將要被設置的值
    glLightfv(GL_LIGHT0, GL_AMBIENT,   light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE,   light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR,  light_specular);

    glEnable (GL_COLOR_MATERIAL); //開啓材質顏料設置功能
    glEnable(GL_LIGHTING);        //啓動光源
    glEnable(GL_LIGHT0);          //光源的顏色爲白色
    glEnable(GL_AUTO_NORMAL);     //執行後,圖形能把光反射到各個方向
    glEnable (GL_NORMALIZE);        //根據函數glNormal的設置條件,啓用法向量
    glEnable(GL_DEPTH_TEST);        //啓用深度測試。根據座標的遠近自動隱藏被遮住的圖形(材料)
    glDepthFunc (GL_LESS);        //深度小的時候才渲染
}
void displayFunc()
{
    glMatrixMode(GL_MODELVIEW);  //對模型視景矩陣操作
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glColor3f(1.0,0.0,0.0);
    glPointSize(1.0);//指定柵格化點的直徑
    glRotated(30,1,0,0);//相乘旋轉矩陣的當前的矩陣
    glRotated(60,0,1,0);
    glRotated(90,0,0,1);
    drawWire();
    glutSwapBuffers();//交換兩個緩衝區指針
}
int main(int argc,char* argv[])
{
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(width,height);
    glutCreateWindow("傻逼球體");

    init();
    glutDisplayFunc(displayFunc);
    glutMainLoop();
}

  • Brensenham算法實現
    這個是實驗要求的題目,老師上課也有講過,我反正覺得這個還蠻重要的,看懂代碼就等於看懂這個劃線方法的思路了,考試還真有可能考這玩意。
    在這裏插入圖片描述
#include<GL/GLUT.H>
#include<stdio.h>
#include<math.h>
int xs,ys,xe,ye;
void BresenhamLine(int x0,int y0,int x1,int y1)   //參數爲兩個點,四個座標
{
	if((x0!=x1)&&(y0!=y1))                        //如果不是一條橫線或豎線
	{
		int x,y,dx,dy,e,i;
		dx=x1-x0;                                 //增量思想,dx,dy都是增量
		dy=y1-y0;
		e=-dx;
		x=x0;
		y=y0;
		for(i=0;i<=dx;i++)                       //在增量的範圍之內
		{
			glVertex2i(x,y);                     //繪製二維座標點
			x=x+1;
			e=e+dy+dy;                           //判斷中點運算後和0的大小比較
			if(e>=0)                             //如果e大於0 ,則取上面的點,反之y=y
			{
				y=y+1;
				e=e-dx-dx;
			}
		}
	}
	else                                        //如果兩點在相同的x或y上
	{
		int min,d;
		if(x0==x1)                             // 如果是豎線
		{
			int x=x0,y;
			y=(y0<=y1)?y0:y1;                  //初始點的位置
			d=fabs((double)(y0-y1));           //求絕對值
			while(d>=0)
			{
				glVertex2i(x,y+d);             //繪製點
				d--;                           //繪製連續的點,直到兩點重合。
			}
		}
		if(y0==y1)                             //同上
		{
			int x,y=y0;
			x=(x0<=x1)?x0:x1;
			d=fabs((double)(x0-x1));
			while(d>=0)
			{
				glVertex2i(x+d,y);
				d--;
			}
		}
	}
}
void lineSegment()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(0.0,0.0,0.0);
	glBegin(GL_POINTS);
	BresenhamLine(xs,ys,xe,ye);              //調用劃線算法
	glEnd();
	glFlush();
}

int main(int argc,char * argv[])
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	printf("輸入起始座標和終點座標(範圍爲0-500  0-500)");
	scanf("%d,%d,%d,%d",&xs,&ys,&xe,&ye);
	glutInitWindowPosition(50,100);
	glutInitWindowSize(500,500);
	glutCreateWindow("Bresenham畫線算法");
	glClearColor(1.0,1.0,1.0,0.0);
	glMatrixMode(GL_PROJECTION);
	gluOrtho2D(0.0,500.0,0.0,500.0);
	glutDisplayFunc(lineSegment);
	glutMainLoop();
}

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