3D Engine code release
Author |
Message |
MihaiG

|
Posted: Mon Nov 24, 2008 6:37 pm Post subject: 3D Engine code release |
|
|
So i decided to release the code to my 3d engine, personally i was fairly pleased at what i did in the allotted time in which i coded the program,
but the way i actually developed the program set up roadblocks in doing zsorting and shading
so here is the code
code: |
View.Set ("offscreenonly")
setscreen ("graphics:max;max")
var zoom : int := 400
var zshift := 3.0
var xshift := 0.0
var yshift := 0.0
var chars : array char of boolean
var pointsize := 1
var perspective := 1
procedure rotz (var x, y : real, theta : real)
var xt, yt : real
xt := x
yt := y
x := xt * cosd (theta) + yt * sind (theta)
y := yt * cosd (theta) - xt * sind (theta)
end rotz
var fileNo : int
open : fileNo, "<filename>", get
var polycount : string
get : fileNo, polycount
var px : array 1 .. strint (polycount), 1 .. 3 of real
var py : array 1 .. strint (polycount), 1 .. 3 of real
var pz : array 1 .. strint (polycount), 1 .. 3 of real
var draw : array 1 .. strint (polycount) of boolean
for i : 1 .. strint (polycount)
draw (i) := true
end for
var t : string
for face : 1 .. strint (polycount)
for point : 1 .. 3
get : fileNo, t
px (face, point) := strreal (t)
get : fileNo, t
py (face, point) := strreal (t)
get : fileNo, t
pz (face, point) := strreal (t)
end for
end for
const xdsip := maxx / 2
const ydsip := maxy / 2
proc drawpoint (x, y, z : real)
Draw.FillOval (round (((x - xshift) / (z * perspective - zshift)) * zoom + xdsip), round (((y - yshift) / (z * perspective - zshift)) * zoom + ydsip), pointsize, pointsize, red)
end drawpoint
proc facedraw (x1, x2, x3, y1, y2, y3, z1, z2, z3 : real)
var fx : array 1 .. 3 of int
var fy : array 1 .. 3 of int
fx (1) := round (((x1 - xshift) / (z1 * perspective - zshift)) * zoom + xdsip)
fx (2) := round (((x2 - xshift) / (z2 * perspective - zshift)) * zoom + xdsip)
fx (3) := round (((x3 - xshift) / (z3 * perspective - zshift)) * zoom + xdsip)
fy (1) := round (((y1 - yshift) / (z1 * perspective - zshift)) * zoom + ydsip)
fy (2) := round (((y2 - yshift) / (z2 * perspective - zshift)) * zoom + ydsip)
fy (3) := round (((y3 - yshift) / (z3 * perspective - zshift)) * zoom + ydsip)
Draw.Polygon (fx, fy, 3, 7)
for i : 1 .. 3
Draw.FillOval (round (fx (i)), round (fy (i)), pointsize, pointsize, red)
end for
end facedraw
proc updatescreen
for face : 1 .. strint ((polycount))
facedraw (px (round (face), 1), px (round (face), 2), px (round (face), 3), py (round (face), 1), py (round (face), 2),
py (round (face), 3), pz (round (face), 1), pz (round (face), 2), pz (round (face), 3))
end for
end updatescreen
var change := true
cls
updatescreen
loop
if change = true then
cls
end if
change := false
Input.KeyDown (chars)
for face : 1 .. strint (polycount)
for point : 1 .. 3
if chars ('e') then
rotz (px (face, point), py (face, point), 2)
change := true
elsif chars ('z') then
rotz (px (face, point), py (face, point), -2)
change := true
end if
if chars ('x') then
rotz (py (face, point), pz (face, point), 2)
change := true
elsif chars ('w') then
rotz (py (face, point), pz (face, point), -2)
change := true
end if
if chars ('d') then
rotz (pz (face, point), px (face, point), 2)
change := true
elsif chars ('a') then
rotz (pz (face, point), px (face, point), -2)
change := true
end if
if chars ('q') then
rotz (px (face, point), py (face, point), 1)
rotz (py (face, point), pz (face, point), 1.5)
rotz (pz (face, point), px (face, point), 2)
change := true
elsif chars ('`') then
quit
end if
end for
end for
if change = true then
updatescreen
View.Update
end if
end loop
|
some tips
the file formating is listed above
to create a model
i just used blender, and imported a model and then used the export function and exported as raw faces using the default values
so just a brief overview of the initial parameters of the program
zoom : basically zooms in its best to have values over 300
zshift moves the object back (sortoff like zoom)
xshift : moves to the right/left
yshift : moves pictures updown
point size defines the size of the vertex of each face
perspective is basically the strength of the camera, so basically having a perspective of 0 will make it have no perspective point, the higher the value, the closer it is to the camera
enjoy
-mihai
|
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
A.J

|
Posted: Mon Nov 24, 2008 6:50 pm Post subject: Re: 3D Engine code release |
|
|
so.......do u have an input file that I can use?
|
|
|
|
|
 |
MihaiG

|
Posted: Mon Nov 24, 2008 9:11 pm Post subject: Re: 3D Engine code release |
|
|
***************NOTE*****************
this is a wireframe only engine
i couldnt get surfaces to work properly
i will be making a completley new engine after winter break
****************************
sorry i forgot to mention,
the input files are on my original submission of the program its just an zip that has the exe inside
http://compsci.ca/v3/viewtopic.php?t=19304
its the second last post in the topic has a bunch of models
you can read that topic as how the data is stored in the files
also
` is quit
w&x are rotation on the x axis
e&z are rotation on the y
a&d are rotation on the z axis
|
|
|
|
|
 |
Zren

|
Posted: Mon Nov 24, 2008 9:26 pm Post subject: Re: 3D Engine code release |
|
|
There's a more efficient way to do 3D polygons in data files. You see here for 1 box you'd have to re write EVERY Point on each polygon. You'd have a 109-line long file. (Example file attached.)
A much number crunching file would be to do as so.
Make two input types: Vertice (Points) and Polygons.
Load the total number of points and polygons (2 lines).
load the vertices. (x,y,z) (3 lines)
Load the polygons (the data here would be the number for the vertice.) (3 lines)
Now, for a basic cube that consists of 8 vertices, and is broken down into 12 polygons:
(2 lines) total numbers
(8*3) points
(12*3) polygons
=62 lines total
A better explanation with pictures is here.
Description: |
|
 Download |
Filename: |
cube.txt |
Filesize: |
380 Bytes |
Downloaded: |
190 Time(s) |
|
|
|
|
|
 |
MihaiG

|
Posted: Mon Nov 24, 2008 11:17 pm Post subject: Re: 3D Engine code release |
|
|
thanks but i probably wont be doing any work on this engine anymore since im having some issues based on the way i developed it
the code is there, so if you want to implement it, be my guest
|
|
|
|
|
 |
A.J

|
Posted: Mon Nov 24, 2008 11:35 pm Post subject: Re: 3D Engine code release |
|
|
good job MihaiG!
I am doing a similar thing but in C++ (for my FP. I am making a 3D Game)
good job!
|
|
|
|
|
 |
MihaiG

|
Posted: Tue Dec 09, 2008 4:53 pm Post subject: Re: 3D Engine code release major update |
|
|
hey guys, im adding a new major update to the code
i now have zsorting so you will draw poly from furthest to closet, i did using saad's quicksort
i also added a kind of pseudo-shading
code: |
View.Set ("offscreenonly")
setscreen ("graphics:max;max")
var zoom : int := 200
var zshift := 3.0
var xshift := 0.0
var yshift := 0.0
var chars : array char of boolean
var pointsize := 1
var perspective := 0.1
var camrate := 0.00005
var ma := 0.0
var mn := 10000.0
var av := 0.0
var rotspeed := 3
procedure rotz (var x, y : real, theta : real)
var xt, yt : real
xt := x
yt := y
x := xt * cosd (theta) + yt * sind (theta)
y := yt * cosd (theta) - xt * sind (theta)
end rotz
var fileNo : int
open : fileNo, "helmet.ply", get
var polycount : string
get : fileNo, polycount
var px : array 1 .. strint (polycount), 1 .. 3 of real
var py : array 1 .. strint (polycount), 1 .. 3 of real
var pz : array 1 .. strint (polycount), 1 .. 3 of real
var draw : array 1 .. strint (polycount) of boolean
for i : 1 .. strint (polycount)
draw (i) := true
end for
var t : string
for face : 1 .. strint (polycount)
for point : 1 .. 3
get : fileNo, t
px (face, point) := strreal (t)
get : fileNo, t
py (face, point) := strreal (t)
get : fileNo, t
pz (face, point) := strreal (t)
end for
end for
const xdsip := maxx / 2
const ydsip := maxy / 2
proc drawpoint (x, y, z : real)
Draw.FillOval (round (((x - xshift) / (z * perspective - zshift)) * zoom + xdsip), round (((y - yshift) / (z * perspective - zshift)) * zoom + ydsip), pointsize, pointsize, red)
end drawpoint
var dis, order : array 1 .. strint (polycount) of real
proc res ()
for i : 1 .. strint (polycount)
order (i) := i
end for
end res
res
proc Swap (var num1, num2 : real)
var tnum := num1
num1 := num2
num2 := tnum
end Swap
proc Quick_Sort (var num : array 1 .. * of real, start, finish : int, var order : array 1 .. * of real)
if start < finish then
var pivot := num (start)
var up := start
var down := finish
loop
exit when up >= down
loop
exit when up > finish or num (up) > pivot
up += 1
end loop
loop
exit when down < start or num (down) <= pivot
down -= 1
end loop
if (up < down) then
Swap (num (up), num (down))
Swap (order (up), order (down))
elsif (up > down) then
Swap (num (start), num (down))
Swap (order (start), order (down))
Quick_Sort (num, start, down - 1, order)
Quick_Sort (num, down + 1, finish, order)
end if
end loop
end if
end Quick_Sort
proc facedraw (x1, x2, x3, y1, y2, y3, z1, z2, z3 : real)
var fx : array 1 .. 3 of int
var fy : array 1 .. 3 of int
var ax, ay, az : real
var dist : real
ax := (x1 + x2 + x3) / 3
ay := (y1 + y2 + y3) / 3
az := (z1 + z2 + z3) / 3
fx (1) := round (((x1 - xshift) / (z1 * perspective - zshift)) * zoom + xdsip)
fx (2) := round (((x2 - xshift) / (z2 * perspective - zshift)) * zoom + xdsip)
fx (3) := round (((x3 - xshift) / (z3 * perspective - zshift)) * zoom + xdsip)
fy (1) := round (((y1 - yshift) / (z1 * perspective - zshift)) * zoom + ydsip)
fy (2) := round (((y2 - yshift) / (z2 * perspective - zshift)) * zoom + ydsip)
fy (3) := round (((y3 - yshift) / (z3 * perspective - zshift)) * zoom + ydsip)
dist := sqrt ((ax + xshift) ** 2 + (ay + yshift) ** 2 + (az + zshift) ** 2)
Draw.FillPolygon (fx, fy, 3, round ((16 + (dist - mn) / (ma-mn) * (32 - 17))))
Draw.Polygon (fx, fy, 3, 7)
end facedraw
proc updatescreen
for face : 1 .. strint (polycount)
facedraw (px (round (order (face)), 1), px (round (order (face)), 2), px (round (order (face)), 3), py (round (order (face)), 1), py (round (order (face)), 2),
py (round (order (face)), 3), pz (round (order (face)), 1), pz (round (order (face)), 2), pz (round (order (face)), 3))
end for
end updatescreen
var change := true
proc avg
var ax, ay, az : real
mn := 1000
ma := 0
av := 0
for face : 1 .. strint (polycount)
ax := (px (face, 1) + px (face, 2) + px (face, 3)) / 3
az := (pz (face, 1) + pz (face, 2) + pz (face, 3)) / 3
ay := (py (face, 1) + py (face, 2) + py (face, 3)) / 3
dis (face) := sqrt ((ax + xshift) ** 2 + (ay + yshift) ** 2 + (az + zshift) ** 2)
if dis (face) < mn then
mn := dis (face)
end if
if dis (face) > ma then
ma := dis (face)
end if
av += dis(face)
end for
av :=av/ strint(polycount)
res
Quick_Sort (dis, 1, upper (dis), order)
end
avg
updatescreen
loop
if change then
cls
end if
change := false
Input.KeyDown (chars)
for face : 1 .. strint (polycount)
for point : 1 .. 3
if chars ('e') then
rotz (px (face, point), py (face, point), rotspeed)
change := true
elsif chars ('z') then
rotz (px (face, point), py (face, point), -1 * rotspeed)
change := true
end if
if chars ('x') then
rotz (py (face, point), pz (face, point), rotspeed)
change := true
elsif chars ('w') then
rotz (py (face, point), pz (face, point), -1 * rotspeed)
change := true
end if
if chars ('d') then
rotz (pz (face, point), px (face, point), rotspeed)
change := true
elsif chars ('a') then
rotz (pz (face, point), px (face, point), -1 * rotspeed)
change := true
end if
if chars ('i') then
yshift += camrate
change := true
elsif chars ('m') then
yshift -= camrate
change := true
end if
if chars ('h') then
xshift += camrate
change := true
elsif chars ('k') then
xshift -= camrate
change := true
end if
if chars ('u') then
zshift += camrate
change := true
elsif chars ('n') then
zshift -= camrate
change := true
end if
if chars ('r') then
xshift := 0
yshift := 0
change := true
end if
if chars ('q') then
rotz (px (face, point), py (face, point), 3*rotspeed)
rotz (py (face, point), pz (face, point), 1.5 * rotspeed)
rotz (pz (face, point), px (face, point), 2 * rotspeed)
change := true
elsif chars ('`') then
exit
end if
end for
end for
if change = true then
avg
updatescreen
View.Update
end if
end loop
|
|
|
|
|
|
 |
Homer_simpson

|
Posted: Wed Dec 10, 2008 4:08 pm Post subject: Re: 3D Engine code release |
|
|
i like it...+ bits
|
|
|
|
|
 |
Sponsor Sponsor

|
|
 |
MihaiG

|
Posted: Wed Dec 10, 2008 7:32 pm Post subject: Re: 3D Engine code release |
|
|
thanks homer
it achieves around 20+fps on 500 polygon models, my assumption is that if you use low detail polygons.
i know that i didn't document much, but if you need any clarification with what code does feel free to send me an email at
mihail[dot]gheorghe[at]gmail[dot]com
i should respond within a day.
also, id like to thank saad again for letting me steal his quicksort code ;P
if anyone is interested in how i did the shading here it is..
when i found the distance to each face, i store a max and a min
then when calculating the color
i took the actual distance and subtracted the min which gave me the delta, i then divided that by the difference between the max and the min, which essential means that, the farther away the darker it is the closer the lighter, this is a bit buggy cause if you have disproportionate models, you will have an "uneven" lighting system,
if someone figures out a more consistant way to do realistic lighting, remember light intensity is proportional to the inverse of the sqaure of the distance
anyways, i know there are many places efficiency can be imroved probably using taylor series for some of the functions (ill try to implement that now)
|
|
|
|
|
 |
A.J

|
Posted: Wed Dec 10, 2008 11:28 pm Post subject: Re: 3D Engine code release |
|
|
where can i find helmet.ply?
|
|
|
|
|
 |
MihaiG

|
Posted: Thu Dec 11, 2008 10:49 am Post subject: Re: 3D Engine code release |
|
|
hey i attached the helmet.ply below
its not a wel designed model cause there are erroneous polygons inside the helmet :/
the helmet probably gives the best result with the 3d engine
note you need to change the file extension back to ply, compsci.ca doesnt allow *.ply uploads , i know its listed as a jpg, your gonna have to right click and save target as ....
Description: |
|
Filesize: |
44.19 KB |
Viewed: |
5022 Time(s) |

|
|
|
|
|
|
 |
Homer_simpson

|
Posted: Thu Dec 11, 2008 12:31 pm Post subject: Re: 3D Engine code release |
|
|
for proper lighting effect you need to find the normal to each face and find the angle between your face normal to your light source and calculate the color based on that.
you can look at the code off my old engine, i had normal calculations in there.
http://compsci.ca/v3/viewtopic.php?t=6503
|
|
|
|
|
 |
MihaiG

|
Posted: Thu Dec 11, 2008 1:20 pm Post subject: Re: 3D Engine code release |
|
|
homer,
i understand as to how to calculate the normal to a plane in 3d space, but how do i know which side it would be facing? because there would be "two' normals that spring of any plane?
or would the correct vector be calculated assuming each polygon's verticies are stored in the same order? ie CW or CCW?
**edit**
ya ifigured it out, i also read up on backface culling if anyone is interested
http://www.cubic.org/docs/backcull.htm
ie. if the normal of a polygon is facing away (ie if the Z value is less than 0) we can skip drawing it
|
|
|
|
|
 |
|
|