Author Topic: Simple 3D for EGSL  (Read 5008 times)

Bereb

  • Guest
Simple 3D for EGSL
« on: November 20, 2012, 03:06:59 PM »
A simple 3D demo :

Code: [Select]
#!/usr/bin/egsl
-----------------------
-- screen set
-----------------------
openwindow(650,450,32,"3D demo - EGSL")
backcolour(255,255,255)
colour(0,0,0)
clearscreen()

---------------------------
-- constants & variables
---------------------------
rad = math.rad
ox, oy = screenwidth()/2, screenheight()/2
coorx, coory = 0, 0
pen = true
heading = 0

--------------------------------
-- main graphic function
--------------------------------
function pos(x,y)
-- draw if pen is down (== true)
if pen then aaline(ox+coorx, oy-coory, ox+x, oy-y) end
-- set new position
coorx, coory = x, y
end

-----------------
-- 3D functions
-----------------
function isopoint(a,b,c)
pos( (a-c)*0.886 , b-(a+c)*0.5 )
end

function cone(r,l)
r = l/2
-- set at point (0,0,0)
pen = false
local h, v
for h = 0, l, 10 do
for v = 0, 360, 20 do
isopoint( (h/2)*cos(rad(v)), h, (h/2)*sin(rad(v)) )
pen = true
end
pen = false
end
for v = 0, 360, 20 do
for h = 0, l, 10 do
isopoint( (h/2)*cos(rad(v)), h, (h/2)*sin(rad(v)) )
pen= true
end
pen = false
end
end

function ellipsoid(r1, r2, r3)
-- set at point (100,-30,100)
local u, v, l, m, n
pen = false
for u = 0, 360, 20 do
for v = 0, 180, 20 do
l = (r1 * cos(rad(u))) * sin(rad(v))
m = r3 * sin(rad(u))
n = (r2 * cos(rad(u))) * cos(rad(v))
isopoint(100 + l, -30 + m, 100 + n)
pen = true
end
pen= false
end
for v = 0, 180, 20 do
for u = 0, 360, 20 do
l = (r1 * cos(rad(u))) * sin(rad(v))
m = r3 * sin(rad(u))
n = r2 * cos(rad(u)) * cos(rad(v))
isopoint(100 + l, -30 + m, 100 + n)
pen = true
end
pen = false
end
end

function cylinder(r, l)
-- set at point (120,-100,-120)
local h, v
pen= false
for h = 0, l, 10 do
for v = 0, 360, 20 do
isopoint( 120+r*cos(rad(v)), -100+h, -120+r*sin(rad(v)) )
pen = true
end
pen = false
end
for v = 0, 360, 20 do
for h = 0, l, 10 do
isopoint( 120+r*cos(rad(v)), -100+h, -120+r*sin(rad(v)) )
pen = true
end
pen= false
end
end

function sphere(r)
-- set at point (-120,-100,120)
local u, v, l, m, n
pen = false
for u = 0, 360, 20 do
for v = 0, 180, 20 do
l = (r * cos(rad(u))) * sin(rad(v))
m = r * sin(rad(u))
n = (r * cos(rad(u))) * cos(rad(v))
isopoint(-120 + l, -100 + m, 120 + n)
pen= true
end
pen = false
end
for v = 0, 180, 20 do
for u = 0, 360, 20 do
l = (r * cos(rad(u))) * sin(rad(v))
m = r * sin(rad(u))
n = (r * cos(rad(u))) * cos(rad(v))
isopoint(-120 + l, -100 + m, 120 + n)
pen= true
end
pen = false
end
end

---------------------------------
-- 3D demo : main program                                   
---------------------------------
sphere(40)
cone(40, 70)
cylinder(30, 90)
ellipsoid(60, 40, 25)

redraw()

inkey()
closewindow()

Bereb

  • Guest
Re: Simple 3D for EGSL
« Reply #1 on: November 20, 2012, 03:09:15 PM »
A rotating pyramid :

Code: [Select]
#!/usr/bin/egsl
openwindow(400,360,0,"Rotating Pyramid - EGSL")
backcolor(100,100,100)
clearscreen()
color(255,255,255)

local ox, oy = screenwidth()/2, screenheight()/2 -- center of screen
local taille = 100
local alpha, beta = 0, 30
local rad = math.rad
local key
local ax, ay, bx, by, cx, cy, dx, dy

repeat
key = getkey()
clearscreen()
-- building pyramid
ax = taille * cos(rad(alpha))
ay = sin(rad(beta)) * taille * sin(rad(alpha))
bx = taille * cos(rad((alpha + 90) % 360))
by = sin(rad(beta)) * taille * sin(rad((alpha + 90) % 360))
cx = taille * cos(rad((alpha + 180) % 360))
cy = sin(rad(beta)) * taille * sin(rad((alpha + 180) % 360))
dx = taille * cos(rad((alpha + 270) % 360))
dy = sin(rad(beta)) * taille * sin(rad((alpha + 270) % 360))
-- drawing pyramid
aaline(ox, oy-120, ox+ax, oy-ay)
aaline(ox, oy-120, ox+bx, oy-by)
aaline(ox, oy-120, ox+cx, oy-cy)
aaline(ox, oy-120, ox+dx, oy-dy)
aaline(ox+ax, oy-ay, ox+bx, oy-by)
aaline(ox+bx, oy-by, ox+cx, oy-cy)
aaline(ox+cx, oy-cy, ox+dx, oy-dy)
aaline(ox+dx, oy-dy, ox+ax, oy-ay)
redraw()
-- rotating pyramid
alpha = alpha+1
until key == 27

closewindow()

Sorry, I've not translated my whole script ... taille means size  ;)
« Last Edit: November 20, 2012, 03:11:36 PM by Bereb »

Bereb

  • Guest
Re: Simple 3D for EGSL
« Reply #2 on: November 20, 2012, 03:37:51 PM »
A cone :

Code: [Select]
openwindow(400,400,8,"CONE")
backcolour(255,255,255)
colour(0,0,0)
clearscreen()

-- constants
local rad = math.rad
local ox, oy = screenwidth()/2, screenheight()/2

-- variables
local x, y, h, beta = 0, 0, 0, 0, 0

-- main loop
repeat
key = getkey()
clearscreen()
for alpha = 0, 360, 8 do
x = 100 * cos(rad(alpha))
y = sin(rad(alpha)) * sin(rad(beta)) * 80
h = 100 * cos(rad(beta))
aaline(ox, oy, ox+x, oy-(y - h))
end
redraw()
beta = beta + 2
until key == 27

closewindow()

Faster without anti-aliasing ( i.e. line() instead of aaline() )
« Last Edit: November 20, 2012, 03:41:28 PM by Bereb »

Cybermonkey

  • Administrator
  • *****
  • Posts: 0
Re: Simple 3D for EGSL
« Reply #3 on: November 20, 2012, 03:55:48 PM »
Awesome. Who starts coding an ELITE clone?  8)

Peter

  • Guest
Re: Simple 3D for EGSL
« Reply #4 on: November 20, 2012, 07:43:31 PM »
good work.  what about textures?

Bereb

  • Guest
Re: Simple 3D for EGSL
« Reply #5 on: November 21, 2012, 03:08:00 PM »
good work.  what about textures?

It's just simple 3D. I'm not clever enough to end up doing that  ???
;D

Cybermonkey

  • Administrator
  • *****
  • Posts: 0
Re: Simple 3D for EGSL
« Reply #6 on: November 21, 2012, 03:14:19 PM »
Maybe not textures but coloured sides? Like in the ELITE for AMIGA ...



I would recommend using filltriangle ...  ;)
« Last Edit: November 21, 2012, 03:21:54 PM by Cybermonkey »

Cybermonkey

  • Administrator
  • *****
  • Posts: 0
Re: Simple 3D for EGSL
« Reply #7 on: November 21, 2012, 03:30:15 PM »
This could be helpful: http://www.codeproject.com/Articles/170296/3D-Software-Rendering-Engine-Part-I
I think I will have a closer look myself ...

Bereb

  • Guest
Re: Simple 3D for EGSL
« Reply #8 on: November 21, 2012, 04:11:42 PM »
We can take a look at Object Oriented Programming in Lua to see if we could create easily this way graphic objects (e.g. a set of filled triangles), to  build more complex 3D objects with some properties and methods.

When I used Windows, I liked Elica Logo, which is a modern 'Logo' using NOOP (Natural Object Oriented Programing) in a very simple manner. This Logo is able to exploit 3D graphics in the easiest way, with awesome performances (best performances than in its 2D graphics features). But that Logo implementation is not cross-platform.

However, personally, I'm not a real advanced programer to find good solutions or to assure any good results   :-[
« Last Edit: November 21, 2012, 04:57:09 PM by Bereb »

Bereb

  • Guest
Re: Simple 3D for EGSL
« Reply #9 on: November 22, 2012, 10:29:08 AM »
I'll try to illustrate my previous remark with a quickly done script, using a table for a very simple 2D object prototype:

Moving square
Code: [Select]
local rad = math.rad
local width  = 400
local height = 400
local bcol = 255 -- background color = white
local fcol = 0 -- foreground color = black

local xcor, ycor, heading, i, pen = 0, 0, 0, 1, true

local coor = {x = 0, y = 0}
local polygon = {nsides = 4, size = 30, pos = coor, orientation = 0}
local square = polygon
square.size = 80

------------------------------------------------------------------
-- Graphic procedures (basic procedures for polar/turtle graphics)
------------------------------------------------------------------
function setpos(x, y)
-- set new position
if pen then
-- draw if pen is down (=true)
line(xcor, ycor, x, y)
end
xcor, ycor = x, y
end

function turn(d)
-- set orientation in degree (right: positive d / left: negative d)
heading = (heading + d) % 360
end

function go(dist)
-- move (forward: positive dist / backward: negative dist)
setpos(xcor + (dist * sin(rad(heading))), ycor + (dist * cos(rad(heading))))
end

------------------------------------------------------------------
-- Polygon procedures
------------------------------------------------------------------
function draw_polygon(poly)
for n = 1, poly.nsides do
go(poly.size)
turn(360 / poly.nsides)
end
end

function display_polygon(poly, mode)
local col = fcol
if not mode then col = bcol end
color(col, col, col)
pen = false
setpos(poly.pos.x, poly.pos.y)
heading = poly.orientation
pen = true
draw_polygon(poly)
end

------------------------------------------------------------------
-- Main program
------------------------------------------------------------------
openwindow(width, height, 0, "Moving Square - EGSL")
backcolor(bcol, bcol, bcol)
color(fcol, fcol, fcol)
clearscreen()

repeat
k = getkey()
display_polygon(square, false)
if (square.pos.x > width or square.pos.x < 0) or (square.pos.y > height or square.pos.y < 0) then
i = 1
else
i = i + 2
end
square.pos.x = i + 2
square.pos.y = i + 2
square.orientation = i * 2
display_polygon(square, true)
        redraw()
until k == 27

closewindow()


We could probably do better with tables and metatables (very interesting Lua's features) as decribed here, and create more complex objects  :)
But no solution this way to fill objects with color or texture  :(
« Last Edit: November 24, 2012, 12:52:20 PM by Bereb »