@Caleb
Alright. Based on your 3d in 2d DBC example, I put together a line function in a dll to draw directly to the backbuffer. It's about 10 times as fast as using the built in DBC line command directly on bitmap 0. I did no optimization to your code. I just ran your code straight but set it up to use the DLL.
So, first try your original code:
sync on
sync rate 0
set display mode 800,600,32
dim v(1000, 2)
dim poly(1000, 2)
dim obj(1000, 1000)
dim objpos(1000, 2)
dim objangle#(1000, 2)
dim camx(0)
dim camy(0)
dim camz(0)
dim CamAng#(2)
dim MatrixScale(3, 3)
dim MatrixRotation#(4, 4)
dim MatrixPosition(3, 3)
camx(0) = 0 : camY(0) = 10 : camz(0) = -50
ink rgb(255,255,255),rgb(0,0,255)
CreateBox(0, 0, 10, 0)
SetMatrixRotationX(0, 180.0)
obj = 0
px = 0
py = 0
pz = 0
do
print screen fps()
camAngleX# = wrapvalue(camAngleX#+mousemovey()/3.0)
camAngleY# = wrapvalue(camAngleY#+mousemovex()/3.0)
RotateCamera(camAngleX#, camAngleY#, 0.0)
xang# = xang# + 1
if leftkey() then px = px - 1
if rightkey() then px = px + 1
if upkey() then py = py + 1
if downkey() then py = py - 1
PositionObject(0, px, py, pz)
RotateObjectZ(0, wrapvalue(zang#))
SetMatrixRotationY(0, xang#)
for x=0 to 12
Draw_Poly(0, x)
next x
sync
cls
loop
function PositionObject(obj, x, y, z)
objpos(obj, 0) = x
objpos(obj, 1) = y
objpos(obj, 2) = z
endfunction
function RotateObjectZ(obj, ang#)
ObjAngle#(obj, 2) = ang#
endfunction
function RotateObjectX(obj, ang#)
ObjAngle#(obj, 0) = ang#
endfunction
function GetVertexScreenX(x#, z#, camx, camz)
if camz ! z#
hw = 400
zdist# = 300/tan(31)
screenX = ( ( (x# - camx) * zdist# ) / (z# - camz) ) + hw
else
screenX = -1
endif
endfunction screenX
function GetVertexScreenY(y#, z#, camy, camz)
if camz ! z#
hh = 300
zdist# = 300/tan(31)
screenY = hh - ( ( (y# - camy) * zdist# ) / (z# - camz) )
else
screenY = -1
endif
endfunction screenY
function CreateBox(obj, x, y, z)
rem front face vertices
v(0, 0) = -5 : v(0, 1) = -5 : v(0, 2) = -5
v(1, 0) = -5 : v(1, 1) = 5 : v(1, 2) = -5
v(2, 0) = 5 : v(2, 1) = 5 : v(2, 2) = -5
v(3, 0) = 5 : v(3, 1) = -5 : v(3, 2) = -5
rem from face polys
poly(0, 0) = 0 : poly(0, 1) = 1 : poly(0, 2) = 2
poly(1, 0) = 3 : poly(1, 1) = 2 : poly(1, 2) = 1
rem left face vertices
v(4, 0) = -5 : v(4, 1) = -5 : v(4, 2) = 5
v(5, 0) = -5 : v(5, 1) = 5 : v(5, 2) = 5
rem left face polys
poly(3, 0) = 4 : poly(3, 1) = 5 : poly(3, 2) = 1
poly(4, 0) = 0 : poly(4, 1) = 5 : poly(4, 2) = 1
rem back face vertices
v(6, 0) = 5 : v(6, 1) = -5 : v(6, 2) = 5
v(7, 0) = 5 : v(7, 1) = 5 : v(7, 2) = 5
rem back face polys
poly(5, 0) = 6 : poly(5, 1) = 7 : poly(5, 2) = 5
poly(6, 0) = 4 : poly(6, 1) = 7 : poly(6, 2) = 5
rem right face vertices
poly(7, 0) = 3 : poly(7, 1) = 2 : poly(7, 2) = 7
poly(8, 0) = 6 : poly(8, 1) = 2 : poly(8, 2) = 7
rem top face polys
poly(9, 0) = 1 : poly(9, 1) = 5 : poly(9, 2) = 7
poly(10, 0) = 2 : poly(10, 1) = 5 : poly(10, 2) = 7
rem bottom face polys
poly(11, 0) = 4 : poly(11, 1) = 0 : poly(11, 2) = 6
poly(12, 0) = 3 : poly(12, 1) = 6: poly(12, 2) = 4
poly(13, 0) = 0 : poly(13, 1) = 3 : poly(13, 2) = 6
obj(obj, 0) = 0 : obj(obj, 1) = 1
for w=2 to 12
obj(obj, w) = w+1
next w
objpos(obj, 0) = 10 : objPos(obj, 1) = 5 : objPos(obj, 2) = 10
endfunction
function RotateCamera(xang#, yang#, zang#)
CamAng#(0) = xang#
CamAng#(1) = yang#
CamAng#(2) = zang#
endfunction
function Draw_Poly(obj,p)
p = obj(obj, p)
dim screenPos(2, 1)
obax# = objangle#(obj, 0) : obay# = objangle#(obj, 1) : obaz# = objangle#(obj, 2)
objX = objpos(obj, 0) : objY = objpos(obj, 1) : objZ = objpos(obj, 2)
camAngX# = CamAng#(0) : camAngY# = CamAng#(1) : camAngZ# = CamAng#(2)
camx = camx(0)
camy = camz(0)
camz = camy(0)
for v=0 to 2
ovx = v(poly(p, v), 0)
ovy = v(poly(p, v), 1)
ovz = v(poly(p, v), 2)
vx# = (ovx*MatrixRotation#(1,1)) + (ovy*MatrixRotation#(2,1)) + (ovz*MatrixRotation#(3,1))
vy# = (ovz*MatrixRotation#(1,2)) + (ovy*MatrixRotation#(2,2)) + (ovz*MatrixRotation#(3,2))
vz# = (ovx*MatrixRotation#(1,3)) + (ovy*MatrixRotation#(2,3)) + (ovz*MatrixRotation#(3,3))
screenPos(v, 0) = GetVertexScreenX(vx#,vz#,camx(0),camz(0))
screenPos(v, 1) = GetVertexScreenY(vy#,vz#,camy(0),camz(0))
next v
DrawWire(screenPos(0,0),screenPos(0,1),screenPos(1,0),screenPos(1,1),screenPos(2,0),screenPos(2,1))
endfunction
function SetMatrixRotationY(Obj, angle#)
angle# = wrapvalue(angle#)
s# = sin(angle#)
c# = cos(angle#)
MatrixRotation#(1, 1) = c# : MatrixRotation#(2, 1) = 0 : MatrixRotation#(3, 1) = 0-s#
MatrixRotation#(1, 2) = 0 : MatrixRotation#(2, 2) = 1 : MatrixRotation#(3, 2) = 0
MatrixRotation#(1, 3) = s# : MatrixRotation#(2, 3) = 0 : MatrixRotation#(3, 3) = c#
endfunction
function SetMatrixRotationX(Obj, angle#)
angle# = wrapvalue(angle#)
s# = sin(angle#)
c# = cos(angle#)
MatrixRotation#(1, 1) = 1 : MatrixRotation#(2, 1) = 0 : MatrixRotation#(3, 1) = 0
MatrixRotation#(1, 2) = 0 : MatrixRotation#(2, 2) = c# : matrixRotation#(3, 2) = 0-s#
MatrixRotation#(1, 3) = 0 : MatrixRotation#(2, 3) = s# : MatrixRotation#(3, 3) = c#
endfunction
function SetMatrixRotationZ(Obj, angle#)
angle# = wrapvalue(angle#)
s# = sin(angle#)
c# = cos(angle#)
MatrixRotation#(1, 1) = c# : MatrixRotation#(2, 1) = 0-s# : MatrixRotation#(3, 1) = 0
MatrixRotation#(1, 2) = s# : MatrixRotation#(2, 2) = c# : matrixRotation#(3, 2) = 0
MatrixRotation#(1, 3) = 0 : MatrixRotation#(2, 3) = s# : MatrixRotation#(3, 3) = 1
endfunction
function DrawWire(ax,ay,bx,by,cx,cy)
line ax,ay,bx,by
line ax,ay,cx,cy
line bx,by,cx,cy
endfunction
Now try the code below with the DLL call. The DLL is attached to the post.
remstart
==============================================================
= Title : 3d in 2d based on Caleb1994 example
= Author : Dll bline function by latch
= Date : 02/22/2010
= Update :
= Version: .01
==============================================================
Comments Using a previous 3d to 2d example written by Caleb1994,
this variation attempts t0 prove that drawing lines
directly to the backbuffer through a DLL is much
faster than doing the same in DBC directly using
native commands.
None of Calebs original code has been changed -
i.e. there are no optimizations save the replacement
of the DBC line command with bline from the DLL. This
also affects Darw_Poly()
The look of it is a little different just for my
own clarity.
==============================================================
remend
rem =============================================================
rem = SET UP DISPLAY
rem =============================================================
autocam off
set display mode 800,600,32
sync on
sync rate 0
rem =============================================================
rem = MAIN
rem =============================================================
_main:
gosub _init:
do
rem get the backbuffer specifications
gosub _querybb
print screen fps()
camAngleX# = wrapvalue(camAngleX#+mousemovey()/3.0)
camAngleY# = wrapvalue(camAngleY#+mousemovex()/3.0)
RotateCamera(camAngleX#, camAngleY#, 0.0)
xang# = xang# + 1
if leftkey() then px = px - 1
if rightkey() then px = px + 1
if upkey() then py = py + 1
if downkey() then py = py - 1
PositionObject(0, px, py, pz)
RotateObjectZ(0, wrapvalue(zang#))
SetMatrixRotationY(0, xang#)
for x=0 to 12
Draw_Poly(0, x, bbdll, bbptr,statptr, c)
next x
rem faster than drawing directly on bitmap 0
`copy bitmap 1,0
sync
cls
loop
end
rem =============================================================
rem = SUBROUTINES - PROCEDURES
rem =============================================================
_init:
rem load in the DLL
bbdll=1
load dll "bbline.dll",bbdll
remstart
latch
create a memblock that holds the specifications of
the back buffer and pass the information as a pointer
to the dll
position:
0 == bbwidth
4 == bbheight
8 == bbdepth
12 == bbpitch
remend
bbmem=1
make memblock bbmem,16
statptr=get memblock ptr(bbmem)
remstart
from Calebs code - initialize variables
remend
dim v(1000, 2)
dim poly(1000, 2)
dim obj(1000, 1000)
dim objpos(1000, 2)
dim objangle#(1000, 2)
dim camx(0)
dim camy(0)
dim camz(0)
dim CamAng#(2)
dim MatrixScale(3, 3)
dim MatrixRotation#(4, 4)
dim MatrixPosition(3, 3)
camx(0) = 0 : camY(0) = 10 : camz(0) = -50
ink rgb(255,255,255),rgb(0,0,255)
CreateBox(0, 0, 10, 0)
SetMatrixRotationX(0, 180.0)
obj = 0
px = 0
py = 0
pz = 0
rem set default color of line to white
c=rgb(255,255,255)
return
`----------------------------------------------------------------
_querybb:
lock backbuffer
bbptr=get backbuffer ptr()
write memblock dword bbmem,0,get backbuffer width()
write memblock dword bbmem,4,get backbuffer height()
write memblock dword bbmem,8,get backbuffer depth()
write memblock dword bbmem,12,get backbuffer pitch()
unlock backbuffer
return
rem =============================================================
rem = FUNCTIONS
rem =============================================================
function PositionObject(obj, x, y, z)
objpos(obj, 0) = x
objpos(obj, 1) = y
objpos(obj, 2) = z
endfunction
`----------------------------------------------------------------
function RotateObjectZ(obj, ang#)
ObjAngle#(obj, 2) = ang#
endfunction
function RotateObjectX(obj, ang#)
ObjAngle#(obj, 0) = ang#
endfunction
`----------------------------------------------------------------
function GetVertexScreenX(x#, z#, camx, camz)
if camz ! z#
hw = 400
zdist# = 300/tan(31)
screenX = ( ( (x# - camx) * zdist# ) / (z# - camz) ) + hw
else
screenX = -1
endif
endfunction screenX
`----------------------------------------------------------------
function GetVertexScreenY(y#, z#, camy, camz)
if camz ! z#
hh = 300
zdist# = 300/tan(31)
screenY = hh - ( ( (y# - camy) * zdist# ) / (z# - camz) )
else
screenY = -1
endif
endfunction screenY
`----------------------------------------------------------------
function CreateBox(obj, x, y, z)
rem front face vertices
v(0, 0) = -5 : v(0, 1) = -5 : v(0, 2) = -5
v(1, 0) = -5 : v(1, 1) = 5 : v(1, 2) = -5
v(2, 0) = 5 : v(2, 1) = 5 : v(2, 2) = -5
v(3, 0) = 5 : v(3, 1) = -5 : v(3, 2) = -5
rem from face polys
poly(0, 0) = 0 : poly(0, 1) = 1 : poly(0, 2) = 2
poly(1, 0) = 3 : poly(1, 1) = 2 : poly(1, 2) = 1
rem left face vertices
v(4, 0) = -5 : v(4, 1) = -5 : v(4, 2) = 5
v(5, 0) = -5 : v(5, 1) = 5 : v(5, 2) = 5
rem left face polys
poly(3, 0) = 4 : poly(3, 1) = 5 : poly(3, 2) = 1
poly(4, 0) = 0 : poly(4, 1) = 5 : poly(4, 2) = 1
rem back face vertices
v(6, 0) = 5 : v(6, 1) = -5 : v(6, 2) = 5
v(7, 0) = 5 : v(7, 1) = 5 : v(7, 2) = 5
rem back face polys
poly(5, 0) = 6 : poly(5, 1) = 7 : poly(5, 2) = 5
poly(6, 0) = 4 : poly(6, 1) = 7 : poly(6, 2) = 5
rem right face vertices
poly(7, 0) = 3 : poly(7, 1) = 2 : poly(7, 2) = 7
poly(8, 0) = 6 : poly(8, 1) = 2 : poly(8, 2) = 7
rem top face polys
poly(9, 0) = 1 : poly(9, 1) = 5 : poly(9, 2) = 7
poly(10, 0) = 2 : poly(10, 1) = 5 : poly(10, 2) = 7
rem bottom face polys
poly(11, 0) = 4 : poly(11, 1) = 0 : poly(11, 2) = 6
poly(12, 0) = 3 : poly(12, 1) = 6: poly(12, 2) = 4
poly(13, 0) = 0 : poly(13, 1) = 3 : poly(13, 2) = 6
obj(obj, 0) = 0 : obj(obj, 1) = 1
for w=2 to 12
obj(obj, w) = w+1
next w
objpos(obj, 0) = 10 : objPos(obj, 1) = 5 : objPos(obj, 2) = 10
endfunction
`----------------------------------------------------------------
function RotateCamera(xang#, yang#, zang#)
CamAng#(0) = xang#
CamAng#(1) = yang#
CamAng#(2) = zang#
endfunction
`----------------------------------------------------------------
function Draw_Poly(obj,p,bbdll,bbptr,statptr,c)
p = obj(obj, p)
dim screenPos(2, 1)
obax# = objangle#(obj, 0) : obay# = objangle#(obj, 1) : obaz# = objangle#(obj, 2)
objX = objpos(obj, 0) : objY = objpos(obj, 1) : objZ = objpos(obj, 2)
camAngX# = CamAng#(0) : camAngY# = CamAng#(1) : camAngZ# = CamAng#(2)
camx = camx(0)
camy = camz(0)
camz = camy(0)
for v=0 to 2
ovx = v(poly(p, v), 0)
ovy = v(poly(p, v), 1)
ovz = v(poly(p, v), 2)
vx# = (ovx*MatrixRotation#(1,1)) + (ovy*MatrixRotation#(2,1)) + (ovz*MatrixRotation#(3,1))
vy# = (ovz*MatrixRotation#(1,2)) + (ovy*MatrixRotation#(2,2)) + (ovz*MatrixRotation#(3,2))
vz# = (ovx*MatrixRotation#(1,3)) + (ovy*MatrixRotation#(2,3)) + (ovz*MatrixRotation#(3,3))
screenPos(v, 0) = GetVertexScreenX(vx#,vz#,camx(0),camz(0))
screenPos(v, 1) = GetVertexScreenY(vy#,vz#,camy(0),camz(0))
next v
bbDrawWire(bbdll,bbptr,statptr,c,screenPos(0,0),screenPos(0,1),screenPos(1,0),screenPos(1,1),screenPos(2,0),screenPos(2,1))
endfunction
`----------------------------------------------------------------
function SetMatrixRotationY(Obj, angle#)
angle# = wrapvalue(angle#)
s# = sin(angle#)
c# = cos(angle#)
MatrixRotation#(1, 1) = c# : MatrixRotation#(2, 1) = 0 : MatrixRotation#(3, 1) = 0-s#
MatrixRotation#(1, 2) = 0 : MatrixRotation#(2, 2) = 1 : MatrixRotation#(3, 2) = 0
MatrixRotation#(1, 3) = s# : MatrixRotation#(2, 3) = 0 : MatrixRotation#(3, 3) = c#
endfunction
`----------------------------------------------------------------
function SetMatrixRotationX(Obj, angle#)
angle# = wrapvalue(angle#)
s# = sin(angle#)
c# = cos(angle#)
MatrixRotation#(1, 1) = 1 : MatrixRotation#(2, 1) = 0 : MatrixRotation#(3, 1) = 0
MatrixRotation#(1, 2) = 0 : MatrixRotation#(2, 2) = c# : matrixRotation#(3, 2) = 0-s#
MatrixRotation#(1, 3) = 0 : MatrixRotation#(2, 3) = s# : MatrixRotation#(3, 3) = c#
endfunction
`----------------------------------------------------------------
function SetMatrixRotationZ(Obj, angle#)
angle# = wrapvalue(angle#)
s# = sin(angle#)
c# = cos(angle#)
MatrixRotation#(1, 1) = c# : MatrixRotation#(2, 1) = 0-s# : MatrixRotation#(3, 1) = 0
MatrixRotation#(1, 2) = s# : MatrixRotation#(2, 2) = c# : matrixRotation#(3, 2) = 0
MatrixRotation#(1, 3) = 0 : MatrixRotation#(2, 3) = s# : MatrixRotation#(3, 3) = 1
endfunction
`----------------------------------------------------------------
function bbDrawWire(bbdll,bbptr,statptr,c,ax,ay,bx,by,cx,cy)
remstart
this function is being replaced
` function DrawWire(ax,ay,bx,by,cx,cy)
`
` line ax,ay,bx,by
` line ax,ay,cx,cy
` line bx,by,cx,cy
` endfunction
remend
rem draw lines directly on the back buffer
call dll bbdll,"bline",bbptr,statptr,c,ax,ay,bx,by
call dll bbdll,"bline",bbptr,statptr,c,ax,ay,cx,cy
call dll bbdll,"bline",bbptr,statptr,c,bx,by,cx,cy
endfunction
`----------------------------------------------------------------
Enjoy your day.