天天看點

VS2010搭配OpenGL配置個人筆記

VS2010搭配OpenGL配置個人筆記

由于最近畢業論文要做平面塊體切割程式需要判斷多邊形的凹凸性,是以在網上找了一段C++代碼作為研究Open gl判斷任意多邊形的凹凸性。程式源代碼如下:

/*  數學知識補充:
将向量用坐标表示(三維向量), 
若向量a=(a1,b1,c1),向量b=(a2,b2,c2), 
則 
向量a·向量b=a1a2+b1b2+c1c2    ------------向量點乘 
向量a×向量b=                  ------------向量叉乘
| i j k| 
|a1 b1 c1| 
|a2 b2 c2| 
=(b1c2-b2c1,c1a2-a1c2,a1b2-a2b1) 
(i、j、k分别為空間中互相垂直的三條坐标軸的機關向量)。
*/
#include <iostream>
#include <vector>
#include <iterator>
#include "glut.h"
using namespace std;
struct vertex 
{
	vertex(GLint _x,GLint _y):x(_x),y(_y)
	{
	}
	GLint x;
	GLint y;
};

class side    
{
public:
	side(vertex _begin,vertex _end):begin(_begin),end(_end)
	{
		x=end.x-begin.x;
		y=end.y-begin.y;
		z=0;
	}

public:
	vertex begin;
	vertex end;

	GLint x;
	GLint y;
	GLint z;
};

// 一個全局函數,求2個邊的差積
GLint getchajiZ(const side& left,const side& right)
{
	// (a1,b1,c1) (a2,b2,c2)
	// z=a1b2-a2b1
	return left.x * right.y - right.x * left.y;
}

vector<vertex> vecVertex;    // 因為頂點的數量不固定,由使用者左擊次數決定,是以采用vector向量容器
vector<side>   vecSide;
vector<int>    vecZ;

void init(void)
{

	glClearColor(0.0,0.0, 1.0, 1.0);

	glMatrixMode(GL_PROJECTION);//設定投影矩陣
	gluOrtho2D(0.0, 400.0, 0.0, 300.0);//二維視景區域

	glColor3f(1.0,0.0,0.0);
	glPointSize(13.0);//點的大小
}

void displayFcn(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	glBegin(GL_POLYGON);                     // 繪制模式
	glColor3f(200.0f,270.0f,0.0f);

	vector<vertex>::iterator it=vecVertex.begin();
	int i=0;
	for(;it!=vecVertex.end();it++,i++)
	{

		if (it!=vecVertex.begin())     // 先取得每個邊的向量儲存到容器vecSide
		{
			side aSide(vecVertex[i-1],vecVertex[i]);
			vecSide.push_back(  aSide );                     
		}
		glVertex3i((*it).x,(*it).y,0);       // 畫出一個頂點

		if (i == vecVertex.size() -1 )  
		{
			side aSide(vecVertex[i],vecVertex[0]);   // 還有一個首尾相連的邊
			vecSide.push_back(  aSide ); 
		}
	}

	// 現在想辦法得到chajiZ  ---差積的z
	int size=vecSide.size();
	for (i=0;i<size;i++)
	{
		int chajiZ;
		chajiZ=getchajiZ(vecSide[i],vecSide[(i+1)%size]);

		vecZ.push_back(chajiZ);
		cout<<chajiZ<<endl;                    // 列印出每個差積的z值
	}
	for (i=0;i<vecZ.size();i++)
	{
		if (vecZ[i]*vecZ[ (i+1) % vecZ.size() ] <0  )  // 有異号
		{
			cout<<"凹多邊形!!!!!!!"<<endl;
			break;
		}

		if(i==vecZ.size()-1)
		{
			cout<<"凸多邊形!!!"<<endl;
			break;
		}
	}

	glEnd();
	glFlush();
}

void plotpoint(GLint x, GLint y)
{
	// 畫出臨時的一個點
	glBegin(GL_POINTS);
	glVertex2i(x,y);
	glEnd();

	vecVertex.push_back(vertex(x,y));    // 不用new,全局vector容器儲存局部對象可以的
}

void mouse(GLint button, GLint action, GLint x,GLint y)
{
	if (button==GLUT_LEFT_BUTTON && action==GLUT_DOWN)
	{
		plotpoint(x,300-y);
	}
	glFlush();

	if (button==GLUT_RIGHT_BUTTON && action==GLUT_DOWN)
	{
		glutPostRedisplay();//重繪視窗  
		//	vecVertex.clear();     // 發現一旦清除,就不能顯示了
		//  這邊順便判斷下是否為凸多邊形(所有向量差積的z都同号)		
	}	
}

void main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowPosition(50, 100);
	glutInitWindowSize(400, 300);
	glutCreateWindow("mouse");

	init();
	glutDisplayFunc(displayFcn);
	glutMouseFunc(mouse);  
	glutMainLoop();

}
           

一、下載下傳GLUT工具包

GLUT不是OpenGL所必須的,但它會給我們的學習帶來一定的友善,推薦安裝。

Windows環境下的GLUT下載下傳位址:(大小約為150k)

http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip

該工具包包含了上述代碼所需要的glut.h頭檔案,GLUT代表OpenGL應用工具包,英文全稱為OpenGL Utility Toolkit,是一個和視窗系統無關的軟體包,它由Mark Kilgard在SGI時寫的。作為AUX庫的功能更強大的替代品,用于隐藏不同視窗系統API的複雜性,是一個學習OpenGL程式設計的一個良好開端。

二、GLUT工具包在VS2010,WIN10 64系統下的安裝配置

首先解壓下載下傳下來的GLUT安裝包,出現以下5個檔案:

VS2010搭配OpenGL配置個人筆記

将glut.h檔案拷貝一份到VS2010的安裝目錄下的include檔案夾中,在我的電腦中的路徑為:D:\Apps\Microsoft Visual Studio 10.0\VC\include

将glut.lib,glut32.lib靜态連結庫拷貝到:D:\Apps\Microsoft Visual Studio 10.0\VC\lib

将glut.dll,glut32.dll動态連結庫拷貝到:C:\Windows\SysWOW64(如果是32位電腦,則拷貝到:C:\Windows\System32)

(注:如在開發應用程式時用到OpenGL輔助庫函數,則還需下載下傳相應動态連結庫,包含glaux.dll, glaux.lib, glaux.h,相應步驟同上)

三、第一個OpenGL程式的配置

在VS2010中先右擊項目,選擇屬性,找到連接配接器标簽,最後在輸入中的附加依賴庫加上opengl32.lib glut32.lib glu32.lib.(注意三者之間用分号連接配接)

VS2010搭配OpenGL配置個人筆記

編譯,執行上述代碼,得結果為:

VS2010搭配OpenGL配置個人筆記

       main函數中以glut開頭的函數都包含在glut.h中。GLUT庫的函數主要執行如處理多視窗繪制、處理回調驅動事件、生成層疊式彈出菜單、繪制位圖字型和筆畫字型,以及各種視窗管理等任務。

       glutInit用來初始化GLUT庫并同視窗系統對話協商。

       glutInitDisplayMode用來确定所建立視窗的顯示模式。參數GLUT_SINGLE 指定單緩存視窗,這也是預設模式,對應的模式為GLUT_DOUBLE 雙緩存視窗。參數GLUT_RGB指定顔色RGBA模式,這也是預設模式,對應的模式為GLUT_INDEX 顔色索引模式視窗。

       glutInitWindowSize 初始化視窗的大小,第一個參數為視窗的寬度,第二個參數為視窗的高度,以像素為機關。

       glutInitWindowPosition 設定初始視窗的位置,第一個參數為視窗左上角x的坐标,第二個參數為視窗左上角y的坐标,以像素為機關。螢幕的左上角的坐标為(0,0),橫坐标向右逐漸增加,縱坐标向下逐漸增加。

       glutCreateWindow 建立頂層視窗,視窗的名字為擴号中的參數。

       glutDisplayFunc 注冊目前視窗的顯示回調函數。當一個視窗的圖像層需要重新繪制時,GLUT将調用該視窗的的顯示回調函數。在此例中的mydisplay就是顯示回調函數,顯示回調函數不帶任何參數,它負責整個圖像層的繪制。我們的大部分工作将集中在這個函數中。

       glutMainLoop 進入GLUT事件處理循環。glutMainLoop函數在GLUT程式中最多隻能調用一次,它一旦被調用就不再傳回,并且調用注冊過的回調函數。是以這個函數必須放在注冊回調函數的後面,此例中為glutDisplayFunc 。

繼續閱讀