开发者

3D Graphics Theory and Code without OpenGL, DirectX, XNA, et al [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.

Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.

Closed 9 years ago.

开发者_如何学运维 Improve this question

I was wondering if there was any tutorial that introduces 3D Graphics theory while showing relevant code, without using OpenGL or DirectX or something. I'm very comfortable with engineering math (I'm an A/V DSP student, so I work with a lot of math all the time).

Most of the tutorials I see either show me the same old matrix translation/rotation examples, along with a discussion on projections and show me using similar triangles how projections work or assume you know everything about 3D or just use a bunch of OpenGL primitives. I've ordered a book (Interactive Computer Graphics: A Top-Down Approach) on the topic but I'd like to get started right now.

I'd really like something that just worked with an SDL surface or a Java Graphics2D object and just used matrix math to render everything. I was hoping to be able to do some simple stuff, like rendering some simple shapes before the book arrived. Ideally something that introduced topics and gave coded examples on how they worked.

EDIT: All the answers were great, but I just loved the code. Exactly what I was looking for, even if it was in Pascal ;)


Buried out some old pascal source :D About 14 years ago, I used it for displaying very simple 3d objects. xrot, yrot, zrot are to rotate points ([x,y,z] multiplied by rotation matrix). And I used a very simple 3d-to-2d-transformation, based on vanishing-point projection with the vanishing-point at the middle of the screen. As an example, there is a vertex array defined. You also have to add a trigons array.

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;

For filled trigons, I used a friend's function, which draws the shape using horizontal lines (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;


Get this book

or at least borrow it from your nearest university library.

3D Graphics Theory and Code without OpenGL, DirectX, XNA, et al [closed]


It's a few years old now, but it was (before the programmable shader revolution) considered the graphics bible. You can probably skip a lot of the first couple of chapters about input methods and palletized displays, but pretty much everything else has stood up exceptionally well.


One way to avoid OpenGL and DirectX solutions is to look for older graphics books that predate OpenGL and DirectX - something from the mid 80's for example (OpenGL may have been around, but not in widespread use on the PC). Be prepared to translate from GWBasic or the like. ;>

Or, just pick up a trigonometry textbook. Projecting 3D coords to 2D is nothing but trig and is sometimes covered as an advanced topic in trig books.


This series of articles helped me understand the basics of 3D graphics: Exploring 3D in Flash. The articles are in Actionscript/ECMAScript in a Flash DOM environment but it can easily be translated to other environments.

I personally followed the articles by translating the examples to Tcl/Tk drawing on a Tk canvas. You could try Perl/Tk or TkInter instead or a much closer translation is to javascript using HTML5 canvas or something like Raphael to do the drawing. By the end of the article you will have a simple but usable 3D API.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜