没有OpenGL的3D图形理论和代码,DirectX,XNA等

时间:2010-08-11 00:25:11

标签: java c math sdl 3d

我想知道是否有任何教程在展示相关代码时引入3D图形理论,没有使用OpenGL或DirectX等。我对工程数学很满意(我是一名A / V DSP学生,所以我一直都在学习很多数学)。

我看到的大多数教程都向我展示了相同的旧矩阵平移/旋转示例,以及对投影的讨论,并向我展示使用类似三角形的投影如何工作或假设您了解3D的一切或仅使用一堆OpenGL原语。我订购了一本关于这个主题的书(交互式计算机图形学:一种自上而下的方法)但我现在就想开始。

我真的很喜欢可以使用SDL曲面或Java Graphics2D对象的东西,只是使用矩阵数学来渲染所有东西。我希望能够做一些简单的事情,比如在书到达之前渲染一些简单的形状。理想情况下介绍主题并提供有关其工作方式的编码示例。

编辑:所有的答案都很棒,但我只是喜欢这些代码。正是我在寻找的东西,即使它是在Pascal中;)

4 个答案:

答案 0 :(得分:7)

埋藏了一些旧的pascal来源:D大约14年前,我用它来显示非常简单的三维物体。 xrot,yrot,zrot是旋转点([x,y,z]乘以旋转矩阵)。我使用了一个非常简单的3d-to-2d变换,基于消失点投影和屏幕中间的消失点。例如,定义了一个顶点数组。您还必须添加一个三角形数组。

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;

对于填充三角形,我使用了朋友的函数,它使用水平线(Hline(x,y,width,color))绘制形状:

    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;

答案 1 :(得分:4)

获取本书

或者至少从离你最近的大学图书馆借阅。

Computer graphics, principles and practice


现在已经有几年了,但它(在可编程着色器革命之前)被认为是 图形圣经。您可以跳过关于输入法和托盘化显示的前几章中的很多章节,但几乎所有其他章节都非常出色。

答案 2 :(得分:2)

避免OpenGL和DirectX解决方案的一种方法是寻找早于OpenGL和DirectX的旧图形书籍 - 例如80年代中期的东西(OpenGL可能已经存在,但在PC上没有广泛使用)。准备从GWBasic等翻译。 ;&GT;

或者,只需拿起三角学教科书。将3D坐标投影到2D只不过是三角形,有时被描述为三角书中的高级主题。

答案 3 :(得分:2)

这一系列文章帮助我理解了3D图形的基础知识:Exploring 3D in Flash。这些文章在Flash DOM环境中的Actionscript / ECMAScript中,但它可以很容易地转换到其他环境。

我个人通过将示例翻译成Tk画布上的Tcl / Tk绘图来跟踪文章。您可以尝试使用Perl / Tk或TkInter,或者使用HTML5画布或类似Raphael之类的javascript进行更接近的翻译来进行绘图。在本文结束时,您将拥有一个简单但可用的3D API。