顯示具有 3D 標籤的文章。 顯示所有文章
顯示具有 3D 標籤的文章。 顯示所有文章

2010年9月8日 星期三

Touch Game - Rubik's Cube

之前開發過不少touch相關的應用程式, 其中一個就是Rubik's Cube(中文叫魔術方塊), 關於它的介紹和玩法, 可參考: 維基百科-魔術方塊
Rubik's cube繪圖的部分是透過OpenGL API, 而觸控和手勢則取得透過Win7 Touch SDK.
此遊戲可以利用 "觸控+手勢" 來作操作, 方法如下所示:

Orienting the Cube Touch one finger and move it in the direction you want the cube to rotate

[圖 1] Orienting the cube


Rotating a Cube Section - Touch one finger and move it inside the section you wish to move, and then move it in the direction you want to rotate the section

[圖 2] Rotating a cube section


Zoom In - Touch two fingers and move them farther apart.

[圖 3] Zoom in


Zoom Out - Touch two fingers and move them closer apart

[圖 4] Zoom out


Resetting All Rotations - Touch two fingers and move them in the same direction, entire cube orientation can be reset

[圖 5] Resetting all rotations


Scrambling the Cube - Touch two fingers and turn them in a circle to scramble the cube

[圖 6] Scrambling the cube

2009年8月3日 星期一

WPF功能 - 3D 繪圖

3D繪圖是WPF的特色之一, 利用WPF提供的3D功能, 你可以在應用程式中製做出很棒3D特效.
下面會先介紹WPF 3D繪圖的基本概念, 並且以3D Cube的範例作為說明.


1. 座標系統
圖1 顯示WPF使用的2D和3D座標系, WPF的3D座標系和Direct3D一樣, 是採用右手座標系(OpenGL是使用左手座標系)

[圖 1] 2D和3D座標系統


2. 3D畫布
你可以使用Viewport3D(
投影3D場景的平面)來當作一個3D畫布, 類似2D中Window或Grid.


<Viewport3D>
Children
</Viewport3D>



3. 相機 - Camera
你必須在3D場景中指定相機的位置方向和視野, WPF 提供兩種攝影機, 如下:

a. OrthographicCamera - 垂直投射的攝影機, 它不會因為攝影機的距離而改變尺寸, 適合CAD或2D繪圖

b. PerspectiveCamera - 透視投射的攝影機, 離攝影機越遠的物體, 看起來會縮小和變短, 類似真實世界所看到的影像


另外Camera中還一些參數可設定:
  • Position(攝影機的座標 )
  • LookDirection(攝影機拍攝的方向 )
  • UpDirection(攝影機的法向量 )
  • FiledOfView(攝影機的拍攝角度 , PerspectiveCamera才可以設定)
  • Width(觀景的寬度, OrthographicCamera 才可以設定)
攝影機在XAML的寫法如下所示:


<Viewport3D.Camera>
<PerspectiveCamera x:Name="camera"
Position="0,0,5"
LookDirection="0,0,-10"
UpDirection="0,1,0"
FieldOfView="45" />
</Viewport3D.Camera>


1. 3D模型
- ModelVisual3D

a. Light

如果在3D場景中沒有打光的話, 畫面會是一片黑暗.

WPF提供下面幾種光源, 供使用者使用:

  • AmbientLight(周遭光源, 光線來自四處)
  • DirectionalLight(方向光源, 類似太陽光)
  • PointLight(點光源, 類似燈泡或蠟燭)
  • SpotLight(聚光燈)
下面程式碼(XAML)顯示燈光的使用:

<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight x:Name="light" Direction="-1,-1,-1" Color="White"/>
</ModelVisual3D.Content>
</ModelVisual3D>


b. MeshGeometry3D
WPF是利用
三角形建立來3D模型, 其相關的參數如下:

  • Position(三角形的頂點)
  • TriangleIndices(指定頂點的連接順序)
  • Normals(三角形面的法向量, 可指定正面和反面)
  • TextureCoordinates(指定貼圖座標)
下面的程式碼顯示如何產生一個矩形的平面:


<MeshGeometry3D
Positions="-1 -1 0 1 -1 0 -1 1 0 1 1 0"
Normals="0 0 1 0 0 1 0 0 1 0 0 1"
TextureCoordinates="0 1 1 1 0 0 1 0"
TriangleIndices="0 1 2 1 3 2" />
</GeometryModel3D.Geometry>


c. Material
我們可以為3D模型加上材質, WPF提供下面這些材質來作設定.
  • DiffuseMaterial
  • SpecularMaterial
  • EmissiveMaterial
下列程式碼式碼(XAML)顯示顯示如何使用材質:


<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<SolidColorBrush Color="Cyan">
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>


看完上面介紹後, 我們就用XAML寫一個3D Cube. 程式碼如下所示:

<Window x:Class="WPF3DCube.Window1"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Title="Window1" Height="407" Width="342">

<Grid>

<Viewport3D Name="viewport3D1">



<!--Setup Camera-->

<Viewport3D.Camera>

<PerspectiveCamera

x:Name="camera"

Position="6 5 4"

LookDirection="-6 -5 -4"

FieldOfView="30">

</PerspectiveCamera>

</Viewport3D.Camera>



<!--Setup Light-->

<ModelVisual3D>

<ModelVisual3D.Content>

<DirectionalLight x:Name="light"

Direction="-1,-1,-1"

Color="White"/>

</ModelVisual3D.Content>          

</ModelVisual3D>



<ModelVisual3D>

<ModelVisual3D.Content>                  

<GeometryModel3D>


<!--Build 3D Cube-->

<GeometryModel3D.Geometry>

<MeshGeometry3D x:Name="cube"

Positions="0 0 0  1 0 0
0 1 0  1 1 0
0 0 1  1 0 1
0 1 1  1 1 1"

TriangleIndices="2 3 1  2 1 0  7 1 3
7 5 1  6 5 7  6 4 5
6 2 0  2 0 4  2 7 3
2 6 7  0 1 5  0 5 4">

</MeshGeometry3D>                          

</GeometryModel3D.Geometry>                    



<!--Setup Material-->

<GeometryModel3D.Material>                         

<DiffuseMaterial x:Name="matDiffuseMain">

<DiffuseMaterial.Brush>

<SolidColorBrush Color="Bisque"/>

<DiffuseMaterial.Brush>

</DiffuseMaterial>

</GeometryModel3D.Material>



</GeometryModel3D>

</ModelVisual3D.Content>

</ModelVisual3D>

</Viewport3D>

</Grid>
</Window>


其結果如下所示:


[圖 2] 3D Cube

參考文章 :
MSDN - WPF 3D Graphics
CodeProject :
WPF 3D Primer

2009年7月10日 星期五

在MFC中使用OpenGL

這篇文章介紹如何在MFC上使用OpenGL.

1. 產生一個MFC Dialog, 然後引用OpenGL的標頭檔(gl.h, glu.h), 和連結OpenGL的函式庫(opengl32.lib, glu32.lib); 其作法可參考在Windows中使用OpenGL

2. 在ClassWizard增加WM_CREATE訊息處理OnCreate
函式(設定OpenGL RC);


部分程式碼所下所示:

int CMFC_OpenGLDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here

//取得一個DC
m_hDC = ::GetDC(this->GetSafeHwnd());
//調整這個DC的像素格示
if(!SetPixelformat(m_hDC))

{
::MessageBoxA(::GetFocus(),"SetPixelformat Failed!","Error",MB_OK);
return -1;

}

//產生一個OpenGL rendering context
m_hGLRC = wglCreateContext(m_hDC);

//
設置為當前的RC
m_hDC, m_hGLRC); InitGL();
return 0;
}



3.
增加WM_SIZE訊息處理OnSize函式(改變ViewPort)

void CMFC_OpenGLDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
GLsizei width;
GLsizei height;

width = cx;
height = cy;

ReSizeGLScene((GLsizei) width, (GLsizei) height);
}

GLvoid CMFC_OpenGLDlg::ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{

if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}

glViewport(0,0,width,height); // Reset The Current Viewport

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix

// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix

}



4. 增加WM_PAINT訊息處理OnPaint函式(將繪圖函式加在裡面)

void CMFC_OpenGLDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{

DrawGLScene();
SwapBuffers(m_hDC);


CDialog::OnPaint();
}
}


int CMFC_OpenGLDlg::DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0

glBegin(GL_TRIANGLES); // Drawing Using Triangles
glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
glVertex3f( 0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glEnd(); // Finished Drawing The Triangle
glTranslatef(3.0f,0.0f,0.0f); // Move Right 3 Units
glColor3f(0.5f,0.5f,1.0f); // Set The Color To Blue One Time Only
glBegin(GL_QUADS); // Draw A Quad
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
glVertex3f( 1.0f, 1.0f, 0.0f); // Top Right
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom Right
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom Left
glEnd(); /// Done Drawing The Quad

return TRUE; // Keep Going
}


5. 增加WM_DESTROY訊息處理OnDestory函式(釋放不用的DCRC)


void CMFC_OpenGLDlg::OnDestroy()
{
CDialog::OnDestroy();
wglMakeCurrent(NULL,NULL);
wglDeleteContext(m_hGLRC);
}


結果如下面圖式:

2009年7月6日 星期一

在Windows中使用OpenGL

若你是OpenGL的初學者, 你可以透過GLUT(OpenGL Utility Toolkit)函式庫來撰寫3D程式, GLUT會對視窗的功能和顯示作包裝, 讓user可以不用接觸到Windows的東西, 進而簡化學習OpenGL的步驟. 但是如果你是想在Win32, MFC或Windows Form上使用OpenGL, 就必須在視窗上另外作一些設定, 這篇文章介紹, 如何在Win32 Window上使用OpenGL API.

1. 編譯環境設定
a. 連結 OpenGL 函式庫, 在 Visual C++ 的 Project, Setting 中, 點選 Linker. 加上 OpenGL32.lib GLu32.lib, 如下圖所示:


b. 引用OpenGL標頭檔
// Include OpenGL header file
#include <gl\gl.h>
// Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library


2. 修改WNDCLASS和CreateWindowEx的style

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{

WNDCLASS wc;
MSG uMsg;

memset(&uMsg, 0, sizeof(uMsg));

//下面程式碼中, 我們抓到視窗的 instance, 然後就定義視窗類別

g_hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window

wc.lpszClassName = "MY_WINDOWS_CLASS";

//CS_HREDRAW 和 CS_VREDRAW 是用來強迫視窗在改變大小時要重新繪製. CS_OWNDC
//為視窗建立私有的 DC. 也就是指 DC 不能被別的應用程式所共用

wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.hInstance = g_hInstance;
wc.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WIN32GL);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
if( !RegisterClass(&wc) )
return E_FAIL;

g_WinWidth = 1280;
g_WinHeight = 800;

//建立視窗
g_hWnd = CreateWindowEx( NULL,
"MY_WINDOWS_CLASS",
"OpenGL Win32 Window",
//我們在視窗形式上設了 WS_CLIPSIBLINGS 和 WS_CLIPCHILDREN.
//WS_CLIPSIBLINGS 和 WS_CLIPCHILDREN 是必須要的, 這樣 OpenGL 才能
//正常運作. 這些形式的設定可以避免別的視窗畫到我們的 OpenGL 視窗上.
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, g_WinWidth, g_WinHeight,
NULL,
NULL,
g_hInstance,
NULL );

if( g_hWnd == NULL )
return E_FAIL;

ShowWindow(g_hWnd, nCmdShow);
UpdateWindow(g_hWnd);

....................
}



3.使用OpenGL Rendering Context
基本上分成下面幾個步驟:

a. 先取得一個DC(Device Context); 開始在視窗繪圖之前, 一定要有一個Windows Device Context; Windows下的任何繪圖(即時繪製到記憶體內的bitmap)都需要DC以識別被繪製的物件.
b. 調整這個
DC的像素格示(PixelFormat)讓OpenGL進行繪製
c. 用wglCreateContext(hDC)去得到RC(OpenGL的著色區)
d.
wglMakeCurrent(hRC,hDC)將剛才建立的RC變成目前的RC

部分程式碼如下所示:


BOOL CreateGLWindow(int WinWidth, int WinHeight)
{
// 每一個 OpenGL 程式都要連結到一個著色區. 著色區就是連結到 OpenGL 的裝置內容 (Device Context). OpenGL 的著色區定義為 hRC. 為了將你的程式畫到視窗上, 你必須建立一個裝置內容(Device Context). 視窗的裝置內容 (Device Context) 定義為 hDC. 這個 DC 連接到視窗的 GDI (圖形裝置介面). RC 連接 OpenGL 到 DC.

if (!(g_hDC = GetDC(g_hWnd))) // Did We Get A Device Context?
{
KillGLWindow();
MessageBoxA(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

if(!SetupPixelFormat(g_hDC))
{
KillGLWindow();
return FALSE;
}

if (!(g_hRC = wglCreateContext(g_hDC))) // Are We Able To Get A Rendering Context?
{
KillGLWindow(); // Reset The Display
MessageBoxA(NULL,
"Can't Create A GL Rendering Context.",
"ERROR",MB_OK|MB_ICONEXCLAMATION);

return FALSE;
}

if(!wglMakeCurrent(g_hDC,g_hRC)) // Try To Activate The Rendering Context
{
KillGLWindow();

MessageBoxA(NULL,
"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}

ReSizeGLScene(WinWidth, WinHeight); // Set Up Our Perspective GL Screen

if (!InitGL()) // Initialize Our Newly Created GL Window
{

KillGLWindow(); // Reset The Display
MessageBoxA(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
return TRUE;

}



SetupPixelFormat的程式碼如下所示:

// The pixel format is an extension to the Win32 API that is provided for support of OpenGL functionality.

BOOL SetupPixelFormat(HDC hDC)
{
int nPixelFormat;

//這一段程式碼描述一個圖素的格式. 我們選擇一個格式支援 OpenGL 和雙緩衝區, 在 RGBA (紅,綠, 藍, 透明) 狀態. 並且找一個圖素格式符合所選的色彩位元數 (16bit,24bit,32bit). 最後設定 16bit的 Z-緩衝區.

static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of structure.
1, // always 1.
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGl
PFD_DOUBLEBUFFER, // support double buffering
PFD_TYPE_RGBA, // support RGBA
16, // bit color mode
0, 0, 0, 0, 0, 0, // ignore color bits
0, // no alpha buffer
0, // ignore shift bit
0, // no accumulation buffer
0, 0, 0, 0, // ignore accumulation bits
16, // number of depth buffer bits
0, // number of stencil buffer bits
0, // 0 means no auxiliary buffer
PFD_MAIN_PLANE, // The main drawing plane
0, // this is reserved
0, 0, 0 }; // layer masks ignored

// 準備一個裝置內容給 OpenGL 視窗, 並試著找到一個圖素格式符合我們上面所描述的
if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd))) // Did Windows Find A Matching Pixel Format?
{
MessageBoxA(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}

//設定圖素格式.
if(!SetPixelFormat(hDC, nPixelFormat, &pfd)) // Are We Able To Set The Pixel Format?
{
MessageBoxA(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}

return TRUE;
}



4.設定OpenGL View Port
這個函式在程式一開始執行時, 至少會被執行一次, 以設定透視觀點. 在改變視窗大小時, 也必須呼叫此函式, OpenGL 畫面會依據視窗顯示的寬高來調整大小


GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}

glViewport(0,0,width,height); // Reset The Current Viewport

glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix

// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}



4.設定OpenGL的參數

下面這一段程式碼就是用來設定 OpenGL. 我們設定了清除畫面的顏色, 我們開啟深度緩衝區, 以及平滑著色功能, 等等. 這個函式會在 OpenGL 視窗建立後才被呼叫

int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
return TRUE; // Initialization Went OK
}

5.繪製Model
所有繪圖作業的地方, 都放在此函式當中, 在此, 我們繪製一個矩形

int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix

glTranslatef(0.0, 0.0, -10.0);
glColor3f(60.0, 0.0, 230.0);
glRectf(0.0, 0.0, 1.0, 1.0);

return TRUE; // Keep Going
}

while( uMsg.message != WM_QUIT )
{
if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &uMsg );
DispatchMessage( &uMsg );
}
else
{
DrawGLScene();
SwapBuffers(g_hDC);

}
}




6.殺掉 OpenGL 視窗, 並將一切的東西釋放掉

GLvoid KillGLWindow(GLvoid) // Properly Kill The Window
{
if (g_hRC) // Do We Have A Rendering Context?
{
if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts?
{
MessageBoxA(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}

if (!wglDeleteContext(g_hRC)) // Are We Able To Delete The RC?
{
MessageBoxA(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
g_hRC=NULL; // Set RC To NULL
}

if (g_hDC && !ReleaseDC(g_hWnd,g_hDC)) // Are We Able To Release The DC
{
MessageBoxA(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
g_hDC=NULL; // Set DC To NULL
}

if (g_hWnd && !DestroyWindow(g_hWnd)) // Are We Able To Destroy The Window?
{
MessageBoxA(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
g_hWnd=NULL; // Set hWnd To NULL
}

if (!UnregisterClass("MY_WINDOWS_CLASS", g_hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
g_hInstance=NULL; // Set hInstance To NULL
}
}

下面圖示為此範例的結果:

2009年7月5日 星期日

OpenGL帶來的3D世界

還記得多年前, 原本不愛寫程式的我, 卻在大學專題製作中, 開始接觸到OpenGL API, 透過OpenGL呈現的3D視覺效果, 讓我開始enjoy在coding和3D modeling當中. 而這也影響到, 我之後所選擇工作的內容, 不在是老本行(機械相關產業), 而是軟體業或和3D有關聯的工作.
而什麼是OpenGL(Open Graphics Library)呢? 簡單地說就是"公開的標準繪圖介面", 它定義了一個跨程式語言跨平台的編成介面規格,並可用來產生2D3D圖象.

OpenGL可分成兩種版本, 分別為硬體純軟體實作版本。
硬體實作版本會透過ICD(Installable-Client Driver,它是硬體驅動程式的介面)
來辨別是否可以透過硬體處理(OpenGL應用程式會連結opengl32.dll,當應用程式呼叫OpenGL函式,便會把工作交給ICD處理),如果沒有則透過CPU進行運算。
純軟體的版本是使用SGI所提供的靜態函式庫,所有的運算都是透過CPU來達成.


關於OpenGL的相關網站, 有非常多, 可參考下面列出的網址
:

什麼是OpenGL?
OpenGL 教學文件:
http://janusbooks.myweb.hinet.net/opengl/what_is_opengl.html
OpenGL的維基百科 :
http://zh.wikipedia.org/wiki/OpenGL

OpenGL官網:
OpenGL函式庫 : http://www.opengl.org/sdk/docs/man/
OpenGL函式庫: http://www.xmission.com/~nate/opengl.html

OpenGL教學

OpenGL Reference Manual: http://www.glprogramming.com/blue/
OpenGL Programming Guide: http://orion.lcg.ufrj.br/compgraf1/downloads/OpenGL_Programming_Guide/index.html
OpenGL step by step : http://www.pinxue.net/OpenGL/openglstepbystep.htm
OpenGL tutorial: http://www.songho.ca/opengl/index.html
codesample : http://www.codesampler.com/oglsrc.htm

下面的圖示, 是我利用C搭配OpenGL寫出來的作品:
電腦繪圖學


B-Spline curve


NURBS Surface


校徽



Shadow



3D modeling



Mesh


機構設計

正齒輪模擬



魯式鼓風機


凸輪教學軟體



連桿機構


非圓形齒輪