2010-08-11 82 views
7

我想知道是否有任何教程介紹3D圖形理論,同時顯示相關的代碼,沒有使用OpenGL或DirectX什麼的。我對工程數學非常滿意(我是一位A/V DSP學生,所以我一直在進行大量的數學工作)。三維圖形理論和代碼沒有OpenGL,DirectX,XNA等

我看到的大多數教程都向我展示了同樣的舊矩陣翻譯/旋轉示例,以及有關投影的討論,並向我展示瞭如何使用類似三角形預測如何工作或假設您知道關於3D的所有內容或僅使用一堆OpenGL基元。我已經訂購了一本關於這個主題的書(交互式計算機圖形學:自上而下的方法),但我想現在開始。

我真的很喜歡SDL表面或Java Graphics2D對象,只使用矩陣數學渲染一切。我希望能夠做一些簡單的事情,比如在書到達之前渲染一些簡單的形狀。理想情況下,介紹主題並給出他們如何工作的代碼示例。

編輯:所有的答案都很好,但我只是喜歡的代碼。正是我在尋找什麼,即使它在帕斯卡​​爾;)

回答

7

埋沒了一些舊的pascal來源:D大約14年前,我用它來顯示非常簡單的3d對象。 xrot,yrot,zrot將旋轉點([x,y,z]乘以旋轉矩陣)。我使用了非常簡單的3d到2d變換,基於屏幕中間消失點的消失點投影。作爲一個例子,定義了一個頂點數組。你還必須添加一個trigons數組。

const depth = 1500; 
     deg = pi/180; 

     { some vertices for a dice :) } 
     vertices:array[0..23] of real= (50, 50, 50,  { 0} 
           -50, 50, 50,  { 1} 
            50,-50, 50,  { 2} 
           -50,-50, 50,  { 3} 
            50, 50,-50,  { 4} 
           -50, 50,-50,  { 5} 
            50,-50,-50,  { 6} 
           -50,-50,-50,  { 7} 
           ); 

{ transform 3d coordinates to pixel coordinates } 
procedure 3d_to_2d(x, y, z : real; var px, py : longint); 
var k:real; 
begin 
k:=((depth shr 1)+z)/depth; 
px:=(getmaxx shr 1)+trunc(x*k);  { getmaxx is the width of the screen } 
py:=(getmaxy shr 1)+trunc(y*k);  { getmaxy is the height of the screen } 
end; 

{ rotate around the x axis by rx degrees } 
procedure xrot(var x,y,z:real;rx:integer); 
var x1,y1,z1:real; 
begin 
y1:=(y * cos(rx * deg))+(z* (sin(rx * deg))); 
z1:=(-y* sin(rx * deg))+(z* (cos(rx * deg))); 
y:=y1; z:=z1; 
end; 

{ rotate around the y axis by ry degrees } 
procedure yrot(var x,y,z:real;ry:integer); 
var x1,y1,z1:real; 
begin 
x1:=(x * cos(ry * deg))+(z*(sin(ry * deg))); 
z1:=(-x * sin(ry * deg))+(z*(cos(ry * deg))); 
x:=x1; z:=z1; 
end; 

{ rotate around the z axis by rz degrees } 
procedure zrot(var x,y,z:real; rz:integer); 
var x1,y1,z1:real; 
begin 
x1:=(x* cos(rz * deg))+(y*(sin(rz * deg))); 
y1:=(-x* sin(rz * deg))+(y*(cos(rz * deg))); 
x:=x1; y:=y1; 
end; 

對於填充trigons,我使用的朋友的功能,吸引用水平線(HLINE(X,Y,寬度,顏色))的形狀:

TYPE pt=RECORD x,y:LongInt;END; 

PROCEDURE Tri(P:ARRAY OF pt;co:BYTE); 
VAR q,w:INTEGER; 
    S:pt; 
    f12,f13,f23:LongInt; 
    s1,s2:LongInt; 


BEGIN 

    IF p[0].y>p[2].y THEN BEGIN s:=p[0];p[0]:=p[2];p[2]:=s;END; { sort the points } 
    IF p[0].y>p[1].y THEN BEGIN s:=p[0];p[0]:=p[1];p[1]:=s;END; 
    IF p[1].y>p[2].y THEN BEGIN s:=p[1];p[1]:=p[2];p[2]:=s;END; 

    q:=(p[0].y-p[1].y); { y distance between point 0 and 1 } 
    IF q<>0 THEN f12:=LongInt((p[0].x-p[1].x) shl 6) DIV q ELSE f12:=0; 

    q:=(p[0].y-p[2].y); 
    IF q<>0 THEN f13:=LongInt((p[0].x-p[2].x) shl 6) DIV q ELSE f13:=0; 

    q:=(p[1].y-p[2].y); 
    IF q<>0 THEN f23:=LongInt((p[1].x-p[2].x) shl 6) DIV q ELSE f23:=0; 

    s1:=p[0].x shl 6;s2:=s1; 
    FOR q:=p[0].y TO p[1].y DO 
    BEGIN 
    Hline(s1 shr 6,s2 shr 6,q,co); 
    s1:=s1+f12; 
    s2:=s2+f13; 
    END; 
    s1:=p[2].x shl 6;s2:=s1; 
    FOR q:=p[2].y DOWNTO p[1].y DO 
    BEGIN 
    Hline(s1 shr 6,s2 shr 6,q,co); 
    s1:=s1-f23; 
    s2:=s2-f13; 
    END; 
END; 
+2

pascal的+1:D – Seth 2010-08-11 04:23:46

2

避免OpenGL和DirectX解決方案的一種方法是尋找早於OpenGL和DirectX的舊圖形書 - 例如從80年代中期開始(OpenGL可能已經出現,但在PC上沒有廣泛使用)。準備從GWBasic等翻譯。 ;>

或者,只需拿起三角學教科書。將3D座標投影到2D不過是觸發,有時候被作爲觸發書中的高級主題加以討論。

+0

如何填充形狀和東西? – GrayGnome 2010-08-11 00:36:35

+0

80年代中期是有點太遙遠了(可能足夠遠,任何代碼示例都不會在C++中)。我有一些90年代後期編寫的遊戲編程書籍,詳細討論了軟件3D - 數據結構,幾何體,渲染模式,優化等。(第一批消費者3D硬件加速器直到1996年纔開始大規模投入市場)。 – Seth 2010-08-11 00:43:10

+0

尋找SIGGRAPH論文。他們涵蓋了很多類似的東西。 – dthorpe 2010-08-11 00:43:32

2

本系列文章幫助我理解3D圖形的基礎知識:Exploring 3D in Flash。這些文章位於Flash DOM環境中的Actionscript/ECMAScript中,但它可以很容易地轉換爲其他環境。

我個人通過將示例翻譯爲Tk畫布上的Tcl/Tk繪圖來跟蹤文章。您可以嘗試使用Perl/Tk或TkInter,或者使用HTML5畫布或類似Raphael來進行更接近的JavaScript繪製。在文章的最後,您將擁有一個簡單但可用的3D API。

4

獲取此書

或至少從最近的大學圖書館借書。

Computer graphics, principles and practice


它現在幾十歲,但它是(可編程着色器革命前)認爲圖形聖經。你可能會跳過很多關於輸入法和碼垛顯示的幾章,但幾乎所有其他的東西都格外出色。

+0

它是我保留的兩本圖形書籍之一(另一本已經失蹤),它比聖經更厚:-)在這裏不會出錯。 – phkahler 2010-08-11 19:03:56