A DIY 3D Rendering Engine

Stuff that don´t fit in the other categories.
Post Reply
User avatar
Gogeta70
^_^
^_^
Posts: 3275
Joined: 25 Jun 2005, 16:00
18

A DIY 3D Rendering Engine

Post by Gogeta70 »

Okay... it's not really a full 3D engine, but still pretty cool.

Anyway, I had a thought last night about rendering a 3d scene using only the Window's API GDI library. This library allows you to do trivial things such as draw a line or point, fill a rectangular area with a certain color, etc.

So today, i did some research on how 3D graphics engines render a 3d object onto the screen. I'd already had some experience with opengl, so i know the basics about 3 coordinate systems and i knew that they used a 4x4 matrix to calculate transformations on 3d objects.

At the start of this little project, my goal was to simply manipulate a single point (aka a vertex) in 3d space, but after researching i learned that any transformation done on a point is also done on all other points related to that object (for example, if you rotate one vertex that makes up a cube, you must rotate the whole cube using the same matrix). I won't go into details, but it was a fun (and frustrating!) time. ^_^

If i do develop this further and it turns into a decent 3D library, this particular "engine" would be most useful for rending complex 3d images (like terragen) or small, simple 3d scenes that you can move around in. Because it uses a high level API, it will never reach the performance levels of true 3D graphics libraries like opengl or direct x, as they make more direct use of things like vram, vertex shaders, and the gpu.

Anyway, i've attached a zip file below that contains the binary and the soure code. You can click and drag the cube around, but it always rotates around the Y-axis at the moment.

Later fellas!
Attachments
3d Graph.zip
(8.67 KiB) Downloaded 161 times
¯\_(ツ)_/¯ It works on my machine...

User avatar
maboroshi
Dr. Mab
Dr. Mab
Posts: 1624
Joined: 28 Aug 2005, 16:00
18

Re: A DIY 3D Rendering Engine

Post by maboroshi »

Wow man very cool! I am impressed. This is why we hack. To do the impossible!

*cheers

Mabo

User avatar
bad_brain
Site Owner
Site Owner
Posts: 11636
Joined: 06 Apr 2005, 16:00
19
Location: In your eye floaters.
Contact:

Re: A DIY 3D Rendering Engine

Post by bad_brain »

yeah man, I told gogeta already that I would have not the slightest clue even where to start... :lol: :oops:
Image

Necrix
The Hacker Wolf
The Hacker Wolf
Posts: 746
Joined: 09 Apr 2005, 16:00
19
Location: United States
Contact:

Re: A DIY 3D Rendering Engine

Post by Necrix »

Man that's really cool!

I didn't think a cube could be so entertaining haha.
Image
Anime-Planet.com - anime | manga | reviews

User avatar
Gogeta70
^_^
^_^
Posts: 3275
Joined: 25 Jun 2005, 16:00
18

Re: A DIY 3D Rendering Engine

Post by Gogeta70 »

Okay, here's an update. I reworked the rendering engine and added surface objects, so now the engine simply draws from an array of surface objects (which in turn contains the list of vertices for each surface). This allows me to draw the wireframe lines automatically, unlike in the first one where i specified where to draw the lines.

Right now, there are a few issues that i want to fix. First, when you have an object rotating around the Y-axis from a huge distance, the object distorts really bad when it crosses the X-axis (Try this yourself with the version in the first post, just maximise the window and move the cube to the edge of the screen).

Second, when you move the cube close to the corners of the window (or any "large" distance from the center of the window), it seems too distorted, but maybe this is just me.

Third, i would like to have it so that objects behind other objects aren't drawn over objects in front of them. In other words, i don't want to be able to see through the surfaces. I'm not quite sure how to do this yet, maybe you guys have an idea?

Anyway, aside from those three things, it looks pretty good. I've attached an update below. The cube now spins in place regardless of position, and you can still move it around with the mouse.

Later dudes!
Attachments
3d Graph_2.zip
(15.58 KiB) Downloaded 148 times
¯\_(ツ)_/¯ It works on my machine...

User avatar
Gogeta70
^_^
^_^
Posts: 3275
Joined: 25 Jun 2005, 16:00
18

Re: A DIY 3D Rendering Engine

Post by Gogeta70 »

Hi everyone! So i've been doing a lot of research on wikipedia in relation to 3d graphics.

I've gotten to the point where i should be choosing whether i want to use a rasterizer (for animated 3d scenes) or a static 3d rendering method, such as ray tracing. At the moment, i think i'm going to stick with rasterization, but i'll probably implement ray tracing in the future.

Additionally, i've also fixed this first and second problems i mentioned above. The problem was with the method of projection i was using. Orthographic projection works okay for drawings, but not so well for 3d scenes. I'm now using what's called perspective projection, which uses a point behind the screen instead of a point in the distance.

I've also done some reading up about my third issue. There are 2 methods i'm considering right now. The first is z-buffering, which keeps a record of the closest drawn polygon for each pixel. This is fairly fast, but uses a lot of memory (see below). The other method sorts the array of primitives from back to front, so that the ones in the back are drawn first. This method works pretty well and produces minimal artifacts, but is very computationally expensive.

Code: Select all

//Example of z-ordering memory usage

#define ScreenWidth 1024
#define ScreenHeight 768

//Let's just use a signed short. This will give us a range of -32,768 to 32,768

signed short zBuff = new signed short[ScreenWidth * ScreenHeight];

//The z-buffer takes up ScreenWidth * ScreenHeight * sizeof(signed short) (2 bytes)
//So 1024 * 768 * 2 bytes = 1,572,864 bytes = 1,536 kb = 1.5mb
Anyway, this is where i'm at right now. I don't have an update to upload at the moment since the only new thing is the perspective projection.

Thoughts and ideas are welcome!

Later dudes.
¯\_(ツ)_/¯ It works on my machine...

User avatar
Lundis
Distorter of Reality
Distorter of Reality
Posts: 543
Joined: 22 Aug 2008, 16:00
15
Location: Deadlock of Awesome
Contact:

Re: A DIY 3D Rendering Engine

Post by Lundis »

OpenGL uses a depth map at least... I would go for that, I mean, it only uses a few megabytes of memory after all. You probably want to use floats or doubles to represent the depth values though.

You could implement an option to turn the depth testing off if it's not needed, such as if the user specifies all the objects to be rendered in order. :D

User avatar
Gogeta70
^_^
^_^
Posts: 3275
Joined: 25 Jun 2005, 16:00
18

Re: A DIY 3D Rendering Engine

Post by Gogeta70 »

You're talking about the z-buffer method right? The only problem i see with it is that i don't draw the polygons pixel-by-pixel, i draw lines and fill regions with color, as that's much faster.
¯\_(ツ)_/¯ It works on my machine...

User avatar
bergmann
On the way to fame!
On the way to fame!
Posts: 36
Joined: 01 Apr 2010, 16:00
14

Re: A DIY 3D Rendering Engine

Post by bergmann »

Man that's really cool! *thumb*

User avatar
computathug
Administrator
Administrator
Posts: 2693
Joined: 29 Mar 2007, 16:00
17
Location: UK
Contact:

Re: A DIY 3D Rendering Engine

Post by computathug »

Great work G-Man, *thumb*
The devil can cite Scripture for his purpose.
-- William Shakespeare, "The Merchant of Venice"
https://tshirt-memes.com

User avatar
Lundis
Distorter of Reality
Distorter of Reality
Posts: 543
Joined: 22 Aug 2008, 16:00
15
Location: Deadlock of Awesome
Contact:

Re: A DIY 3D Rendering Engine

Post by Lundis »

Gogeta, you've got a point there ^^

But will your method work if half the line is behind an object?

User avatar
Gogeta70
^_^
^_^
Posts: 3275
Joined: 25 Jun 2005, 16:00
18

Re: A DIY 3D Rendering Engine

Post by Gogeta70 »

Thanks guys ^_^

Lundis, implementing the z-buffer method was too much of a hassle, so i went with what's called the "painter's algorithm". All this does is sort each polygon by it's barycenter (the 3-dimensional center of the polygon) from back to front. The C++ STL has a great function for sorting an array in it's algorithms library, so i used that. It works very well.

Anyway, here's a small update. The only new things in this one is the method of projection and i've implemented depth testing, so things look more realistic already :P. The new method of projection got rid of those problems i've had before pretty well, so i'm happy with it. I'm not sure if i'll stick with the same depth testing method, we'll have to see how it does when i have a few thousand polygons on screen.

Here's what i'm currently adding:
-Support for loading Wavefront Object files (*.obj)
-Rotation around an arbitrary axis (in other words, rotation around a user-specified vector)

Might be added soon:
-Basic lighting:
-Ambient light (needs no explanation, right?)
-Directional light. You specify a point in 3d space and surfaces with be lit (and cast in shadow) based on the relative position of the object from the light source.

That's all for now. Merry christmas!
Attachments
3d Graph.zip
(45.02 KiB) Downloaded 135 times
¯\_(ツ)_/¯ It works on my machine...

Post Reply