A. 圖形學編程問題
一些應用需要涉及任意多邊形窗口(含凹多邊形窗口)的裁剪。Weiler-Atherton多邊形裁剪演算法正是滿足這種要求的演算法。
Weiler-Atherton又稱雙邊裁剪法。
我找到了中國地質大的一個有關的教程,其中的演算法過程具體如下:
1、演算法在實現中,需要用到六個數組,分別用來存放:被裁剪多邊形、裁剪窗口、交點數組、插入交點後的被裁剪多邊形、插入交點後的裁剪窗口、輸出多邊形。
2、由於交點具有「入」、「出」標記,因此凡與交點有關的數組都要採用結構數組類型:
struct point
{
double x;
double y;
int flag;
}交點數組,數組3,數組4;
標記flag有三種狀態:
0:非交點;
1:「入」點;
-1:「出」點。
3、求交點時,利用被裁剪多邊形的各邊去對裁剪窗口的各邊求交點:
for(被裁剪多邊形的各邊)
{
…;
for(裁剪窗口的各邊)
{
求有效交點;放入交點數組;
…;
}
}
4、交點的順序插入,意味著要對交點數組排序後再分別插入到數組1、數組2的相應位置上。
5、所謂找「入」點、「出」點,必須根據flag找尋滿足條件的頂點位置。不光數組3中要找「入」點、「出」點,而且找到後還要轉到數組4的相應頂點位置處。對數組4的處理也同上。這種處理在本演算法中大量遇到。
B. 如何系統掌握游戲編程中3D圖形學相關的基礎
計算機圖形學主要是從數學、物理的角度講計算機的圖形圖像,雖然是內容是計算機的,但因為是基礎理論,裡面數學內容很多。現在絕大多數計算機圖形學書都把3D作為最主要的部分。 3D gramming沒聽說過。。。如果你說的是3D graphics,那就是圖形學。如果是3D programming,那指的是3D程序設計的概念原理和具體的代碼實現,包含許多圖形學方面的理論,但學3D programming不一定非要精通圖形學。Direct3D和OpenGL是現在最主流的兩個3D開發平台,最主要的區枯悄別在於OpenGL是沒歲渣開放標准,跨平台,可以在iPhone, Mac, Play station之類平台上開發;Direct3D是Windows專用的。性能方面以前雀含普遍認為OpenGL強,現在差不多,或者D3D略強。目前主流游戲基本上都是用D3D,用OpenGL的不多。 要製作動畫引擎,必須學3D編程,而且必須非常熟悉3D的基本理論和程序設計方法,會用D3D或者OpenGL之一。CG製作分成兩部分,引擎和藝術,從軟體的角度看就是代碼和數據兩部分。一是引擎,要想做出好的引擎必須同時具備扎實的程序設計功底、3D理論知識和數學能力。二是藝術,包括模型,美工,特效等多方面,需要優秀的審美和設計能力,以及熟練使用引擎的能力和比較基礎的編程能力。這兩個部分是差別較大的兩個方向,通常一個人只能選擇二者之一專精。 我想你可能說的是選擇前者,那麼3D動畫原理非常重要,一定要學精。程序設計也非常重要,也一定要精通。 你現在這樣學我個人認為完全正確。與圖形學無關的C++是學習程序的基礎;與編程無關的3D圖形學是3D編程的基礎。打好基礎可以給你未來更大的提升空間。之後再學3D編程,你就會具備設計引擎的能力了。
C. 圖形編程語言有哪幾種
三圍的圖形編程一般就採用兩種主流技術,都和顯卡的支持相關。三維技術是需要硬體提供支持的,因為顯卡可以提供強大的硬體處理能力來幫助我們完成矩陣計算。
OpenGL是目前用的最多的圖形庫,旗下又有用於手機和平板的以及網頁應用的OpenGL ES精簡版本。支持的語言總類眾多,其中主流語言有:C++,Java,Javascript,C#,Objective-C。
DirectX3D主要是用於windows系統。它是由微軟公司開發的一套程序庫。主要用於windows游戲開發,和windows平台的模擬軟體開發。支持的語言也有很多:C++,Java,C#都支持
學哪一種看你喜歡什麼樣的平台以及以後用於什麼目的。各種系統上以及各種語言的library變種和打包版本都各不相同。
D. 圖形學編程
在三維繪圖蓬勃發展的過程中,計算機公司推出了大量的三維繪圖軟體包。其中SGI公司推出的OpenGL,作為一個性能優越的圖形應用程序設計界面(API)異軍突起,取得了很大的成就。它以高性能的互動式三維圖形建模能力和易於編程開發,得到了Microsoft、IBM、DEC、Sun、HP等大公司的認同。因此,OpenGL已經成為一種三維圖形開發標准,是從事三維圖形開發工作的必要工具。
1、初始化OpenGL繪圖環境
1.1 定義顏色格式和緩沖模式
OpenGL提供兩種顏色模式:RGB(RGBA)模式和顏色索引模式(調色板)。在RGBA模式下所有顏色的定義用RGB三個值來表示,有時也加上Alpha值(表示透明度)。RGB三個分量值的范圍都在0和1之間,它們在最終顏色中所佔的比例與它們的值成正比。如:(1、1、0)表示黃色,(0、0、1)表示藍色。顏色索引模式下每個象素的顏色是用顏色索引表中的某個顏色索引值表示(類似於從調色板中選取顏色)。由於三維圖形處理中要求顏色靈活,而且在陰影,光照,霧化,融合等效果處理中RGBA的效果要比顏色索引模式好,所以,在編程時大多採用RGBA模式。
OpenGL提供了雙緩存來繪制圖像。即在顯示前台緩存中的圖像同時,後台緩存繪制第二幅圖像。當後台繪制完成後,後台緩存中的圖像就顯示出來,此時原來的前台緩存開始繪制第三幅圖像,如此循環往復,以增加圖像的輸出速度。
設置窗口顯示模式函數:
void auxInitDisplayMode(
AUX_DOUBLE | // 雙緩存方式
AUX_RGBA // RGBA顏色模式
);
1.2 設置光源
OpenGL的光源大體分為三種:環境光(Ambient light),即來自於周圍環境沒有固定方向的光。漫射光(Diffuse light)來自同一個方向,照射到物體表面時在物體的各個方向上均勻發散。鏡面光(Specular light)則是來自於同一方向,也沿同一個方向反射。全局環境光是一種特殊的環境光,它不來自特於某種定光源,通常做為場景的自然光源。
指定光源函數:
void glLightfv(
Glenum light, // 光源號
Glenum pname, // 指明光源類型:
// GL_DIFFUSE 光源為漫射光光源
// GL_AMBIENT 光源為環境光光源
// GL_SPECULAR 光源為鏡面光光源
const Glfloat* params // 指向顏色向量的指針
);
設置全局環境光函數:
void glLightModelfv(
GL_LIGHT_MODEL_ AMBIENT,
const Glfloat* param // param:指向顏色向量的指針
);
起用光源函數:
void glEnable(GL_LIGHTING);
void glEnable(GL_enum cap); // cap:指明光源號
1.3 設置材質
在OpenGL中,用材料對光的三原色(紅綠藍)的反射率大小來定義材料的顏色。與光源相對應,材料的顏色,也分為環境色,漫反射色和鏡面反射色,由此決定該材料對應不同的光呈現出不同的反射率。由於人所看到物體的顏色是光源發出的光經物體反射後進入眼睛的顏色。所以,物體的顏色是光源的環境光,漫反射光和鏡面反射光與材料的環境色,漫反射色和鏡面反射色的綜合。例如:OpenGL的光源色是(LR、LG、LB),材質色為(MR、MG、MB),那麼,在忽略其他反射效果的情況下,最終進入眼睛的顏色是(LR*MR、LG*MG、LB*MB)。
材質定義函數:
void glMaterialfv(
GLenum face, // 指明在設置材質的哪個表面的顏色。
// 可以是GL_FRONT、GL_BACK、GL_FRONT_AND_BACK
GLenum pname, // 與光源的pname參數相似
const float* params // 指向材質的顏色向量
);
1.4 定義投影方式
也即選擇觀察物體的角度和范圍。由於我們是三維繪圖,所以採用不同的視點和觀察范圍,就會產生不同的觀察效果。由於計算機只能顯示二維圖形,所以在表示真實世界中的三維圖形時,需將三維視景轉換成二維視景。這是產生三維立體效果的關鍵。OpenGL提供了兩種將3D圖形轉換成2D圖形的方式。正投影(Orthographic Projection)和透視投影(Perspective Projection)。其中,正投影指投影後物體的大小與視點的遠近無關,通常用於CAD設計;而透視投影則符合人的心理習慣,離視點近的物體大,離視點遠的物體小。此外,在OpenGL中還要定義投影范圍,只有在該范圍中的物體才會被投射到計算機屏幕上,投影范圍外的物體將被裁減掉。
定義投影范圍(不同的投影方式對應不同函數):
void glOrtho(
GLdouble left, GLdouble right,
// (left,bottom,near)及(right,top,far)分別給出正射投
GLdouble bottom, GLdouble top, // 影投影范圍的左下角和右上角的坐標。
GLdouble near,GLdouble far);
2、定義與Windows介面的系統函數
2.1 定義繪圖窗口的位置
// (x,y)給出窗口左上角坐標
// width及heigh給出窗口的寬高
void auxInitPosition(GLint x,GLint y,GLsizei width, GLsizei heigh);
2.2 定義繪圖窗口的標題
// STR表示窗口標題字串
void auxInitWindow(GLbyte* STR);
2.3 定義繪圖窗口改變時的窗口刷新函數
// 當窗口改變形狀時調指定的回調函數
// NAME表示回調函數名稱
void auxReshapeFunc(NAME);
2.4 定義空閑狀態的空閑狀態函數以實現動畫
// 當系統空閑時調用指定的回調函數
// NAME表示回調函數名稱
void auxIdleFunc(NAME);
2.5 定義場景繪制函數(當窗口更新或場景改變時調用)
// 當窗口需要更新或場景變化時調用
// NAME表示回調函數名稱
void auxMainLoop(NAME);
在VC編輯器下鍵入下述代碼後,保存為後綴是.cpp的C++文件。開始編譯,在「The build command requires an active project workspace」。「Would you like to create a default project workspace」? 的提示後,選擇「是(Y)」。進入「Project」菜單,選擇「Setting」項,彈出「Project Setting」對話框,選擇「Link」項,在「Libaray」欄目中加入OpenGL提供的函數庫:「opengl32.lib glu32.lib glaux.lib」。(注意:在執行程序時,Windows的system目錄下要包含opengl32.dll及glu32.dll兩個動態連接庫)。附源程序代碼:
#include "windows.h"
#include "gl/gl.h"
#include "gl/glaux.h"
#include "gl/glu.h"
#include "math.h"
void myinit()
{
glClearColor(1,1,0,0);
GLfloat ambient[]={.5,.5,.5,0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
GLfloat mat_ambient[]={.8,.8,.8,1.0};
GLfloat mat_diffuse[]={.8,.0,.8,1.0};
GLfloat mat_specular[]={1.0,.0,1.0,1.0};
GLfloat mat_shininess[]={50.0};
GLfloat light_diffuse[]={0,0,.5,1};
GLfloat light_position[]={0,0,1.0,0};
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0,GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
}
void CALLBACK display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
auxSolidSphere(1.0); // 繪制半徑為1.0的實體球
glFlush(); // 強制輸出圖像
auxSwapBuffers(); // 交換繪圖緩存
_sleep(100);
}
void CALLBACK Idledisplay()
{
// x,y滿足x2+y2=0.01。這樣可以使物體沿該圓軌跡運動。
static float x=-.1,y=0.0;
static BOOL mark=TRUE;
static float step=.01;
x+=step;
if(x<=.1&&x>=-.1)
{
if(step>0)
y=sqrt(.01-x*x);
else
y=-sqrt(.01-x*x);
glTranslatef(x,y,0);
}
else
{
step=0-step;
}
display();
}
void CALLBACK myReshape(GLsizei w,GLsizei h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-3.5,3.5,-3.5*(GLfloat)w/(GLfloat)h, 3.5*(GLfloat)w/(GLfloat)h,-10,10);
else
glOrtho(-3.5*(GLfloat)w/(GLfloat)h,3.5* (GLfloat)w/(GLfloat)h,-3.5,3.5,-10,10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void main()
{
auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA);
auxInitPosition(0,0,400,400);
auxInitWindow(" circle ");
myinit();
auxReshapeFunc(myReshape);
auxIdleFunc(Idledisplay);
auxMainLoop(display);
}
給你一個關於VC和OPENGL的網站,不錯的
http://dev.yesky.com/402/2084902.shtml