3D Gaming Project
Post by Ric on Feb 7th, 2016, 8:53pm
DDRM asked to see a demo of my 3D project, so here goes.
I am learning to create 3D graphics for gaming purpose which has to be said is a steep learning curve. It started with a cube:
Code: MODE 3
*REFRESH OFF
DIM points(7,3)
DIM faces(13,5)
DIM temp(13)
points(0,0)=100
points(0,1)=100
points(0,2)=-100
points(1,0)=100
points(1,1)=-100
points(1,2)=-100
points(2,0)=-100
points(2,1)=-100
points(2,2)=-100
points(3,0)=-100
points(3,1)=100
points(3,2)=-100
points(4,0)=100
points(4,1)=100
points(4,2)=100
points(5,0)=100
points(5,1)=-100
points(5,2)=100
points(6,0)=-100
points(6,1)=-100
points(6,2)=100
points(7,0)=-100
points(7,1)=100
points(7,2)=100
x=.05
y=.05
z=.05
REPEAT
PROCcalcangles
PROCfacessetup
PROCfacesorder
CLS
PROCfacesprint
*REFRESH
WAIT 20
x=.1
y=.1
z=.1
UNTIL FALSE
END
DEF PROCcalcangles
PROCrotatex
PROCrotatey
PROCrotatez
ENDPROC
DEF PROCfacesorder
REPEAT
clearpass=0
FOR loop=0 TO 4
testa=faces(12,loop)
testb=faces(12,loop+1)
IF testb>testa THEN PROCsort
NEXT
UNTIL clearpass=0
ENDPROC
DEF PROCsort
FOR loopa=0 TO 13
temp(loopa)=faces(loopa,loop)
faces(loopa,loop)=faces(loopa,loop+1)
faces(loopa,loop+1)=temp(loopa)
clearpass=1
NEXT
ENDPROC
DEF PROCrotatez
FOR loop%=0 TO 7
rota=((points(loop%,0))*COSz)-((points(loop%,1))*SINz)
rotb=((points(loop%,0))*SINz)+((points(loop%,1))*COSz)
points(loop%,0)=rota
points(loop%,1)=rotb
NEXT
ENDPROC
DEF PROCrotatey
FOR loop%=0 TO 7
rota=((points(loop%,0))*COSy)-((points(loop%,2))*SINy)
rotb=((points(loop%,0))*SINy)+((points(loop%,2))*COSy)
points(loop%,0)=rota
points(loop%,2)=rotb
NEXT
ENDPROC
DEF PROCrotatex
FOR loop%=0 TO 7
rota=((points(loop%,1))*COSx)-((points(loop%,2))*SINx)
rotb=((points(loop%,1))*SINx)+((points(loop%,2))*COSx)
points(loop%,1)=rota
points(loop%,2)=rotb
NEXT
ENDPROC
DEF PROCfacessetup
faces(0,0)=points(0,0)
faces(1,0)=points(0,1)
faces(2,0)=points(0,2)
faces(3,0)=points(4,0)
faces(4,0)=points(4,1)
faces(5,0)=points(4,2)
faces(6,0)=points(1,0)
faces(7,0)=points(1,1)
faces(8,0)=points(1,2)
faces(9,0)=points(5,0)
faces(10,0)=points(5,1)
faces(11,0)=points(5,2)
faces(13,0)=1
faces(0,1)=points(0,0)
faces(1,1)=points(0,1)
faces(2,1)=points(0,2)
faces(3,1)=points(3,0)
faces(4,1)=points(3,1)
faces(5,1)=points(3,2)
faces(6,1)=points(1,0)
faces(7,1)=points(1,1)
faces(8,1)=points(1,2)
faces(9,1)=points(2,0)
faces(10,1)=points(2,1)
faces(11,1)=points(2,2)
faces(13,1)=2
faces(0,2)=points(7,0)
faces(1,2)=points(7,1)
faces(2,2)=points(7,2)
faces(3,2)=points(4,0)
faces(4,2)=points(4,1)
faces(5,2)=points(4,2)
faces(6,2)=points(6,0)
faces(7,2)=points(6,1)
faces(8,2)=points(6,2)
faces(9,2)=points(5,0)
faces(10,2)=points(5,1)
faces(11,2)=points(5,2)
faces(13,2)=3
faces(0,3)=points(7,0)
faces(1,3)=points(7,1)
faces(2,3)=points(7,2)
faces(3,3)=points(3,0)
faces(4,3)=points(3,1)
faces(5,3)=points(3,2)
faces(6,3)=points(6,0)
faces(7,3)=points(6,1)
faces(8,3)=points(6,2)
faces(9,3)=points(2,0)
faces(10,3)=points(2,1)
faces(11,3)=points(2,2)
faces(13,3)=4
faces(0,4)=points(0,0)
faces(1,4)=points(0,1)
faces(2,4)=points(0,2)
faces(3,4)=points(4,0)
faces(4,4)=points(4,1)
faces(5,4)=points(4,2)
faces(6,4)=points(3,0)
faces(7,4)=points(3,1)
faces(8,4)=points(3,2)
faces(9,4)=points(7,0)
faces(10,4)=points(7,1)
faces(11,4)=points(7,2)
faces(13,4)=5
faces(0,5)=points(2,0)
faces(1,5)=points(2,1)
faces(2,5)=points(2,2)
faces(3,5)=points(6,0)
faces(4,5)=points(6,1)
faces(5,5)=points(6,2)
faces(6,5)=points(1,0)
faces(7,5)=points(1,1)
faces(8,5)=points(1,2)
faces(9,5)=points(5,0)
faces(10,5)=points(5,1)
faces(11,5)=points(5,2)
faces(13,5)=6
FOR loop=0 TO 5
average=(faces(2,loop)+faces(5,loop)+faces(8,loop)+faces(11,loop))/4
faces(12,loop)=average
NEXT
ENDPROC
DEF PROCfacesprint
FOR loop%=0 TO 5
GCOL 0,faces(13,loop%)
MOVE faces(0,loop%)*2+500,faces(1,loop%)*2+500
MOVE faces(0,loop%)*2+500,faces(1,loop%)*2+500
PLOT 85,faces(3,loop%)*2+500,faces(4,loop%)*2+500
PLOT 85,faces(6,loop%)*2+500,faces(7,loop%)*2+500
PLOT 85,faces(9,loop%)*2+500,faces(10,loop%)*2+500
NEXT
ENDPROC
After this I moved onto
the more complex issue of shading!!
Just copy, paste and RUN.
See you next time.
Re: 3D Gaming Project
Post by Ric on Feb 7th, 2016, 8:56pm
Sorry its not annotated, I was not intending to make the code public.
Re: 3D Gaming Project
Post by Ric on Feb 9th, 2016, 8:35pm
Evening all,
Here are a few more developments in my project.
I realised that in order to create a shading effect I would have to simulate light some how. Vectors are the answer, which aren't that complicated but necessitated a look back at the old GCSE maths books.
First I calculated the vectors from the centre of the object, which worked well, but was never going to work for objects with faces not perpendicular with the origin.
Back to the maths books, Normal vector calculation was needed. Slightly more complicated but still nothing serious.
This was the result:
The calculations are the real time computaions of all the vectors needed.
Code: DIM points(26)
MODE 3
*REFRESH OFF
points(0)=-2
points(1)=0
points(2)=2
points(3)=2
points(4)=0
points(5)=2
points(6)=-2
points(7)=0
points(8)=-2
points(9)=2
points(10)=0
points(11)=-2
x=.01
y=.01
z=.01
REPEAT
PROCprintface
PROCcalcnormal
PROCprintnormal
PROCcalcangles
*REFRESH
REM WAIT 20
CLS
UNTIL INKEY(-99)=-1
END
DEF PROCcalcangles
PROCrotatex
PROCrotatey
PROCrotatez
ENDPROC
DEF PROCrotatez
FOR loop%=0 TO 9 STEP 3
rota=((points(loop%))*COSz)-((points(loop%+1))*SINz)
rotb=((points(loop%))*SINz)+((points(loop%+1))*COSz)
points(loop%)=rota
points(loop%+1)=rotb
NEXT
ENDPROC
DEF PROCrotatey
FOR loop%=0 TO 9 STEP 3
rota=((points(loop%))*COSy)-((points(loop%+2))*SINy)
rotb=((points(loop%))*SINy)+((points(loop%+2))*COSy)
points(loop%)=rota
points(loop%+2)=rotb
NEXT
ENDPROC
DEF PROCrotatex
FOR loop%=0 TO 9 STEP 3
rota=((points(loop%+1))*COSx)-((points(loop%+2))*SINx)
rotb=((points(loop%+1))*SINx)+((points(loop%+2))*COSx)
points(loop%+1)=rota
points(loop%+2)=rotb
NEXT
ENDPROC
DEF PROCprintnormal
points(24)=(points(0)+points(3)+points(6)+points(9))/4
points(25)=(points(1)+points(4)+points(7)+points(10))/4
points(26)=(points(2)+points(5)+points(8)+points(11))/4
GCOL 0,1
MOVE points(24)*100+500,points(25)*100+400
DRAW (points(21)+points(24))*100+500,(points(22)+points(25))*100+400
ENDPROC
DEF PROCcalcnormal
points(12)=points(3)-points(0)
points(13)=points(4)-points(1)
points(14)=points(5)-points(2)
points(15)=points(6)-points(0)
points(16)=points(7)-points(1)
points(17)=points(8)-points(2)
PRINTTAB(0,0)"v1 [";points(12);"]"
PRINTTAB(0,1)" [";points(13);"]"
PRINTTAB(0,2)" [";points(14);"]"
PRINTTAB(18,0)"v2 [";points(15);"]"
PRINTTAB(18,1)" [";points(16);"]"
PRINTTAB(18,2)" [";points(17);"]"
points(18)=(points(13)*points(17))-(points(14)*points(16))
points(19)=(points(14)*points(15))-(points(12)*points(17))
points(20)=(points(12)*points(16))-(points(13)*points(15))
PRINTTAB(36,0)"n1 [";points(18);"]"
PRINTTAB(36,1)" [";points(19);"]"
PRINTTAB(36,2)" [";points(20);"]"
veclen=SQR((points(18)*points(18))+(points(19)*points(19))+(points(20)*points(20)))
points(21)=points(18)/veclen
points(22)=points(19)/veclen
points(23)=points(20)/veclen
PRINTTAB(54,0)"u1 [";points(21);"]"
PRINTTAB(54,1)" [";points(22);"]"
PRINTTAB(54,2)" [";points(23);"]"
ENDPROC
DEF PROCprintface
GCOL 0,15
MOVE points(0)*100+500,points(1)*100+400
MOVE points(0)*100+500,points(1)*100+400
DRAW points(3)*100+500,points(4)*100+400
DRAW points(6)*100+500,points(7)*100+400
DRAW points(9)*100+500,points(10)*100+400
DRAW points(0)*100+500,points(1)*100+400
ENDPROC
The vector required is the red line poking out of the middle of the mock face. u1 is the unit vector which is required to calculate the cosine angle with the light to produce shading.
Happy viewing
Re: 3D Gaming Project
Post by Ric on Feb 9th, 2016, 8:44pm
After this I needed a good sorting algorithm, the one I was using was a simple bubble sort. Soooooooooo sssslllllloooooowwwwww. After a bit of research I plumped for a merge sort.
Code: MODE 3
ON ERROR GOTO 20
DIM faces(1,2047)
DIM tempsort(7,2047)
FOR loop%=0 TO 2047
faces(1,loop%)=RND(5000)
NEXT
offset=2
left=0
right=0
column=0
destcolumn=2
count=0
TIME=0
FOR loop%=0 TO 2047 STEP 2
IF faces(1,loop%)>faces(1,loop%+1) THEN
tempsort(0,loop%)=faces(1,loop%)
tempsort(0,loop%+1)=faces(1,loop%+1)
tempsort(1,loop%)=loop%
tempsort(1,loop%+1)=loop%+1
ELSE
tempsort(0,loop%)=faces(1,loop%+1)
tempsort(0,loop%+1)=faces(1,loop%)
tempsort(1,loop%)=loop%+1
tempsort(1,loop%+1)=loop%
ENDIF
NEXT
WHILE offset<2047
FOR loop%=0 TO 2047 STEP offset*2
REPEAT
IF tempsort(column,loop%+left)>tempsort(column,loop%+right+offset) THEN
tempsort(destcolumn,count)=tempsort(column,loop%+left)
tempsort(destcolumn+1,count)=tempsort(column+1,loop%+left)
left+=1
ELSE
tempsort(destcolumn,count)=tempsort(column,loop%+right+offset)
tempsort(destcolumn+1,count)=tempsort(column+1,loop%+right+offset)
right+=1
ENDIF
count+=1
UNTIL left=offset OR right=offset
IF left=offset THEN
REPEAT
tempsort(destcolumn,count)=tempsort(column,loop%+offset+right)
tempsort(destcolumn+1,count)=tempsort(column+1,loop%+offset+right)
right+=1
count+=1
UNTIL right=offset
ELSE
REPEAT
tempsort(destcolumn,count)=tempsort(column,loop%+left)
tempsort(destcolumn+1,count)=tempsort(column+1,loop%+left)
left+=1
count+=1
UNTIL left=offset
ENDIF
left=0
right=0
NEXT
count=0
column=(column+2) MOD 4
destcolumn=(destcolumn+2) MOD 4
offset*=2
ENDWHILE
PRINT TIME
10 FOR loop%=0 TO 2047
PRINT " "tempsort(1,loop%);" ";tempsort(2,loop%),
NEXT
20 PRINT "COUNT ";count
PRINT "LEFT ";left
PRINT "RIGHT ";right
PRINT "OFFSET ";offset
PRINT "COLUMN ";column
PRINT "DESTCOLUMN ";destcolumn
The code generates a random list of 2047 numbers and then sorts them in to size order (this is needed to place all the faces of an object into relative distance/depth before displaying). The sort takes milli seconds but printing the result takes time. The number on the left is the position the number on the right started in the list.
Happy viewing.
Re: 3D Gaming Project
Post by Ric on Feb 9th, 2016, 8:51pm
It was now time to apply this to the cube.
Here is an all green cube with shading showing the normal vectors and using the merge sort.
Code: REM faces(x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,Az)
REM tempsort(Az,loc,Az,loc,none,Ax,Ay,v1x,v1y,v1z,v2x,v2y,v2z,Nx,Ny,Nz)
MODE 3
REM ON ERROR PROCerror
HIMEM=(LOMEM+500000000) AND -4
REM *REFRESH OFF
DIM points(2,2047)
DIM faces(12,2047)
DIM tempsort(16,2047)
FOR LOOPY=0 TO 2047
FOR LOOPX=0 TO 7
tempsort(LOOPX,LOOPY)=-1000
NEXT
NEXT
FOR LOOPY=0 TO 2047
FOR LOOPX=0 TO 12
faces(LOOPX,LOOPY)=-1000
NEXT
NEXT
points(0,0)=100
points(1,0)=100
points(2,0)=-100
points(0,1)=100
points(1,1)=-100
points(2,1)=-100
points(0,2)=-100
points(1,2)=-100
points(2,2)=-100
points(0,3)=-100
points(1,3)=100
points(2,3)=-100
points(0,4)=100
points(1,4)=100
points(2,4)=100
points(0,5)=100
points(1,5)=-100
points(2,5)=100
points(0,6)=-100
points(1,6)=-100
points(2,6)=100
points(0,7)=-100
points(1,7)=100
points(2,7)=100
x=0.1
y=0.05
z=0.1
PROCfacessetup
REPEAT
REM TIME=0
PROCcalcangles
REM PRINTTAB(0,0);TIME
REM TIME=0
PROCfacessetup
REM PRINTTAB(0,1);TIME
REM TIME=0
PROCcalcZaverages
REM PRINTTAB(0,2);TIME
REM TIME=0
PROCfacesorder
REM PRINTTAB(55,19);TIME
PROCcalcXYaverages
CLS
REM TIME=0
REM PROCprintZs
PROCfindvector
PROCfacesprint
*REFRESH
REM PRINTTAB(0,3);TIME
UNTIL FALSE
END
DEF PROCcalcangles
PROCrotatex
PROCrotatey
PROCrotatez
ENDPROC
DEF PROCcalcZaverages
FOR loop%=0 TO 2047
faces(12,loop%)=(faces(2,loop%)+faces(5,loop%)+faces(8,loop%)+faces(11,loop%))/4
NEXT
ENDPROC
DEF PROCcalcXYaverages
FOR loop%=0 TO 2047
tempsort(6,loop%)=(faces(0,tempsort(1,loop%))+faces(3,tempsort(1,loop%))+faces(6,tempsort(1,loop%))+faces(9,tempsort(1,loop%)))/4
tempsort(7,loop%)=(faces(1,tempsort(1,loop%))+faces(4,tempsort(1,loop%))+faces(7,tempsort(1,loop%))+faces(10,tempsort(1,loop%)))/4
NEXT
ENDPROC
DEF PROCfacesorder
offset=2
left=0
right=0
column=0
destcolumn=2
count=0
TIME=0
FOR loop%=0 TO 2047 STEP 2
IF faces(12,loop%)>faces(12,loop%+1) THEN
tempsort(0,loop%)=faces(12,loop%)
tempsort(0,loop%+1)=faces(12,loop%+1)
tempsort(1,loop%)=loop%
tempsort(1,loop%+1)=loop%+1
ELSE
tempsort(0,loop%)=faces(12,loop%+1)
tempsort(0,loop%+1)=faces(12,loop%)
tempsort(1,loop%)=loop%+1
tempsort(1,loop%+1)=loop%
ENDIF
NEXT
WHILE offset<2047
FOR loop%=0 TO 2047 STEP offset*2
REPEAT
IF tempsort(column,loop%+left)>tempsort(column,loop%+right+offset) THEN
tempsort(destcolumn,count)=tempsort(column,loop%+left)
tempsort(destcolumn+1,count)=tempsort(column+1,loop%+left)
left+=1
ELSE
tempsort(destcolumn,count)=tempsort(column,loop%+right+offset)
tempsort(destcolumn+1,count)=tempsort(column+1,loop%+right+offset)
right+=1
ENDIF
count+=1
UNTIL left=offset OR right=offset
IF left=offset THEN
REPEAT
tempsort(destcolumn,count)=tempsort(column,loop%+offset+right)
tempsort(destcolumn+1,count)=tempsort(column+1,loop%+offset+right)
right+=1
count+=1
UNTIL right=offset
ELSE
REPEAT
tempsort(destcolumn,count)=tempsort(column,loop%+left)
tempsort(destcolumn+1,count)=tempsort(column+1,loop%+left)
left+=1
count+=1
UNTIL left=offset
ENDIF
left=0
right=0
NEXT
count=0
column=(column+2) MOD 4
destcolumn=(destcolumn+2) MOD 4
offset*=2
ENDWHILE
ENDPROC
DEF PROCsort
FOR loopa=0 TO 16
temp(loopa)=faces(loopa,loop)
faces(loopa,loop)=faces(loopa,loop+1)
faces(loopa,loop+1)=temp(loopa)
NEXT
clearpass=1
ENDPROC
DEF PROCrotatez
FOR loop%=0 TO 2047
rota=((points(0,loop%))*COSz)-((points(1,loop%))*SINz)
rotb=((points(0,loop%))*SINz)+((points(1,loop%))*COSz)
points(0,loop%)=rota
points(1,loop%)=rotb
NEXT
ENDPROC
DEF PROCrotatey
FOR loop%=0 TO 2047
rota=((points(0,loop%))*COSy)-((points(2,loop%))*SINy)
rotb=((points(0,loop%))*SINy)+((points(2,loop%))*COSy)
points(0,loop%)=rota
points(2,loop%)=rotb
NEXT
ENDPROC
DEF PROCrotatex
FOR loop%=0 TO 2047
rota=((points(1,loop%))*COSx)-((points(2,loop%))*SINx)
rotb=((points(1,loop%))*SINx)+((points(2,loop%))*COSx)
points(1,loop%)=rota
points(2,loop%)=rotb
NEXT
ENDPROC
Sill a bit juddery, but it is BASIC still.
Happy viewing.
Re: 3D Gaming Project
Post by DDRM on Feb 10th, 2016, 12:14pm
Hi Ric,
I get an error due to the lack of a PROCfacessetup... and I can't just lift it from the original "cube" post since the arrays have changed...
Do you know there is a sortlib which implements Quicksort very quickly? It may or not be a good solution to your problem (and you may want to do it yourself out of principle!).
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on Feb 15th, 2016, 09:56am
Hi D
I must have exceeded the 9000 characters or so. Copy and paste this onto the end of the cube code and it should work! (Probably)
Code: DEF PROCfacessetup
faces(0,0)=points(0,4)
faces(1,0)=points(1,4)
faces(2,0)=points(2,4)
faces(3,0)=points(0,0)
faces(4,0)=points(1,0)
faces(5,0)=points(2,0)
faces(6,0)=points(0,5)
faces(7,0)=points(1,5)
faces(8,0)=points(2,5)
faces(9,0)=points(0,1)
faces(10,0)=points(1,1)
faces(11,0)=points(2,1)
faces(0,1)=points(0,0)
faces(1,1)=points(1,0)
faces(2,1)=points(2,0)
faces(3,1)=points(0,3)
faces(4,1)=points(1,3)
faces(5,1)=points(2,3)
faces(6,1)=points(0,1)
faces(7,1)=points(1,1)
faces(8,1)=points(2,1)
faces(9,1)=points(0,2)
faces(10,1)=points(1,2)
faces(11,1)=points(2,2)
faces(0,2)=points(0,7)
faces(1,2)=points(1,7)
faces(2,2)=points(2,7)
faces(3,2)=points(0,4)
faces(4,2)=points(1,4)
faces(5,2)=points(2,4)
faces(6,2)=points(0,6)
faces(7,2)=points(1,6)
faces(8,2)=points(2,6)
faces(9,2)=points(0,5)
faces(10,2)=points(1,5)
faces(11,2)=points(2,5)
faces(0,3)=points(0,3)
faces(1,3)=points(1,3)
faces(2,3)=points(2,3)
faces(3,3)=points(0,7)
faces(4,3)=points(1,7)
faces(5,3)=points(2,7)
faces(6,3)=points(0,2)
faces(7,3)=points(1,2)
faces(8,3)=points(2,2)
faces(9,3)=points(0,6)
faces(10,3)=points(1,6)
faces(11,3)=points(2,6)
faces(0,4)=points(0,3)
faces(1,4)=points(1,3)
faces(2,4)=points(2,3)
faces(3,4)=points(0,0)
faces(4,4)=points(1,0)
faces(5,4)=points(2,0)
faces(6,4)=points(0,7)
faces(7,4)=points(1,7)
faces(8,4)=points(2,7)
faces(9,4)=points(0,4)
faces(10,4)=points(1,4)
faces(11,4)=points(2,4)
faces(0,5)=points(0,1)
faces(1,5)=points(1,1)
faces(2,5)=points(2,1)
faces(3,5)=points(0,2)
faces(4,5)=points(1,2)
faces(5,5)=points(2,2)
faces(6,5)=points(0,5)
faces(7,5)=points(1,5)
faces(8,5)=points(2,5)
faces(9,5)=points(0,6)
faces(10,5)=points(1,6)
faces(11,5)=points(2,6)
ENDPROC
place=0
FOR loop=0 TO 29
FOR loopa=0 TO 59
faces(0,place)=points(0,(loop*61)+loopa)
faces(1,place)=points(1,(loop*61)+loopa)
faces(2,place)=points(2,(loop*61)+loopa)
faces(3,place)=points(0,(loop*61)+loopa+1)
faces(4,place)=points(1,(loop*61)+loopa+1)
faces(5,place)=points(2,(loop*61)+loopa+1)
faces(6,place)=points(0,(loop*61)+loopa+61)
faces(7,place)=points(1,(loop*61)+loopa+61)
faces(8,place)=points(2,(loop*61)+loopa+61)
faces(9,place)=points(0,(loop*61)+loopa+62)
faces(10,place)=points(1,(loop*61)+loopa+62)
faces(11,place)=points(2,(loop*61)+loopa+62)
place+=1
NEXT
NEXT
ENDPROC
DEF PROCfacesprint
FOR loop%=0 TO 5
REM Create LIGHT vector
lightx=-10000-tempsort(6,loop%)
lighty=-10000-tempsort(7,loop%)
lightz=0-tempsort(0,loop%)
lightveclen=SQR((lightx*lightx)+(lighty*lighty)+(lightz*lightz))
REM Create unit light vector
lightx=lightx/lightveclen
lighty=lighty/lightveclen
lightz=lightz/lightveclen
REM Create unit vector
REM veclen=SQR((tempsort(6,loop%)*tempsort(6,loop%))+(tempsort(7,loop%)*tempsort(7,loop%))+(tempsort(0,loop%)*tempsort(0,loop%)))
REM tempsort(6,loop%)=tempsort(6,loop%)/veclen
REM tempsort(7,loop%)=tempsort(7,loop%)/veclen
REM tempsort(0,loop%)=tempsort(0,loop%)/veclen
REM Create Normal unit vector
veclen=SQR((tempsort(14,loop%)*tempsort(14,loop%))+(tempsort(15,loop%)*tempsort(15,loop%))+(tempsort(16,loop%)*tempsort(16,loop%)))
tempsort(14,loop%)=tempsort(14,loop%)/veclen
tempsort(15,loop%)=tempsort(15,loop%)/veclen
tempsort(16,loop%)=tempsort(16,loop%)/veclen
REM Create angle
angle=(tempsort(14,loop%)*lightx)+(tempsort(15,loop%)*lighty)+(tempsort(16,loop%)*lightz)
REM PRINT TAB(0,4);angle
COLOUR 3,0,255*((angle+1)/2),0
GCOL 0,3
jump=tempsort(1,loop%)
MOVE faces(0,jump)+500,faces(1,jump)+500
MOVE faces(0,jump)+500,faces(1,jump)+500
PLOT 85,faces(3,jump)+500,faces(4,jump)+500
PLOT 85,faces(6,jump)+500,faces(7,jump)+500
PLOT 85,faces(9,jump)+500,faces(10,jump)+500
GCOL 0,15
MOVE tempsort(6,loop%)+500,tempsort(7,loop%)+500
DRAW tempsort(6,loop%)-(tempsort(14,loop%)*100)+500,tempsort(7,loop%)-(tempsort(15,loop%)*100)+500
REM WAIT 1
NEXT
ENDPROC
DEF PROCprintZs
FOR loop%=0 TO 2047
PRINT "";tempsort(0,loop%);" ";tempsort(1,loop%)
WAIT 1
NEXT
PRINT column
END
ENDPROC
DEF PROCfindvector
FOR loop%=0 TO 5
jump=tempsort(1,loop%)
REM NORMAL VECTOR TO PLANE = [P1-P2=V12 THEN P1-P3=V13 THEN V13*V12 (CROSS PRODUCT){(A*B=(A2B3-A3B2),(A3B1-A1B3),(A1B2-A2B1)}]
tempsort(8,loop%)=faces(3,jump)-faces(0,jump)
tempsort(9,loop%)=faces(4,jump)-faces(1,jump)
tempsort(10,loop%)=faces(5,jump)-faces(2,jump)
tempsort(11,loop%)=faces(6,jump)-faces(0,jump)
tempsort(12,loop%)=faces(7,jump)-faces(1,jump)
tempsort(13,loop%)=faces(8,jump)-faces(2,jump)
tempsort(14,loop%)=(tempsort(9,loop%)*tempsort(13,loop%))-(tempsort(10,loop%)*tempsort(12,loop%))
tempsort(15,loop%)=(tempsort(10,loop%)*tempsort(11,loop%))-(tempsort(8,loop%)*tempsort(13,loop%))
tempsort(16,loop%)=(tempsort(8,loop%)*tempsort(12,loop%))-(tempsort(9,loop%)*tempsort(11,loop%))
NEXT
ENDPROC
DEF PROCerror
PRINT TAB(0,0)"X";faces(14,loop%),"Y";faces(15,loop%),"Z";faces(16,loop%)
END
Where or how do I find to D3D or sortlib?
Regards Ric
Re: 3D Gaming Project
Post by Ric on Feb 15th, 2016, 09:58am
Also, the code for each step is getting longer and exceeding 9000 characters, is there a way of posting larger banks of code?
Re: 3D Gaming Project
Post by DDRM on Feb 15th, 2016, 11:29am
Hi Ric,
That's pretty impressive! Bring on the full game... 
In terms of posting code, there is a Wiggio group, though it's not letting me log in at the moment, not sure why - possibly that I've forgotten my password, but it won't send me a reminder either, so it may be more than that. There is also a Yahoo group:
https://groups.yahoo.com/neo/groups/bb4w/conversations/messages
Both have file repositories. You would probably have to join (both are free) in order to post. Then you could post a link, though maybe only members could read it...
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on Feb 17th, 2016, 7:45pm
It may sound obvious, but in order to create the graphics for the game some kind of plotting routine to take a sprite of x,y and transpose it into a rhomboid is needed.
This code does exactly that and to boot it has been designed to use only interger numbers so it can be easily turned into ASM and only to print the pixels required so if you shrink the sprite size to create depth in a gaming view, it does not waste time over printing its self, ok that bit is only 80% efficient, but that can be worked on!!
Code: 10 MODE 3
20 DIM sprite(255,255)
30 REM *********************************************
40 REM * GREATE CHESS BOARD ***
50 REM *********************************************
60 FOR x=0 TO 7
70 FOR y=0 TO 7
80 IF (x MOD 2=1 AND y MOD 2=1) OR (x MOD 2=0 AND y MOD 2=0) THEN
90 FOR xloop=0 TO 31
100 FOR yloop=0 TO 31
110 sprite((x*32)+xloop,(y*32)+yloop)=1
120 NEXT
130 NEXT
140 ELSE
150 FOR xloop=0 TO 31
160 FOR yloop=0 TO 31
170 sprite((x*32)+xloop,(y*32)+yloop)=4
180 NEXT
190 NEXT
200 ENDIF
210 NEXT
220 NEXT
230 REM ************************************
240 REM * PRINT GRID LINES *
250 REM ************************************
260
270 FOR LOOP=0 TO 1000 STEP 100
280 MOVE LOOP,0
290 DRAW LOOP,1000
300 MOVE 0,LOOP
310 DRAW 1000,LOOP
320 NEXT
330 REM ******************************************************************************************
340 REM * IF YOU REMOVE THE GOTO 380, THIS PRINTS THE CHESS BOARD ORTHOGANALLY *
350 REM * AT THE COORDINATES 0,0 *
360 REM ******************************************************************************************
370 GOTO 450
380 FOR xloop=0 TO 255
390 FOR yloop=0 TO 255
400 GCOL 0,sprite(xloop,yloop)
410 MOVE (xloop*2),(yloop*2)
420 DRAW (xloop*2),(yloop*2)
430 NEXT
440 NEXT
450 VDU 23,65,&FF,&FF,&FF,&FF,&FF,&FF,&FF,&FF :REM *** ANYONE KNOW WHY THIS COMMAND DOESNT WORK?? ***
460 VDU 5
470 GCOL 0,15
480 MOVE 0,1000
490 PRINT"The origional tile being transfered is a chessboard, 256x256 pixels."
500 PRINT"Choose the coordinates for nodes 0,1,2 and 3 and watch"
510 PRINT""
520 PRINT"Node order is N2 N3"
530 PRINT""
540 PRINT""
550 PRINT""
560 PRINT" N0 N1"
570 MOVE 0,500
580 GCOL 0,0
590 PRINT"AAAAAAAAAA"
600 MOVE 0,500
610 GCOL 0,15
620 INPUT"N0x ";x0
630 IF x0<0 OR x0>1000 THEN 570
640 MOVE 0,450
650 GCOL 0,0
660 PRINT"AAAAAAAAAA"
670 MOVE 0,450
680 GCOL 0,15
690 INPUT"N0y ";y0
700 IF y0<0 OR y0>1000 THEN 640
710 MOVE 0,400
720 GCOL 0,0
730 PRINT"AAAAAAAAAA"
740 MOVE 0,400
750 GCOL 0,15
760 INPUT"N1x ";x1
770 IF x1<0 OR x1>1000 THEN 710
780 MOVE 0,350
790 GCOL 0,0
800 PRINT"AAAAAAAAAA"
810 MOVE 0,350
820 GCOL 0,15
830 INPUT"N1y ";y1
840 IF y1<0 OR y1>1000 THEN 780
850 MOVE 0,300
860 GCOL 0,0
870 PRINT"AAAAAAAAAA"
880 MOVE 0,300
890 GCOL 0,15
900 INPUT"N2x ";x2
910 IF x2<0 OR x2>1000 THEN 850
920 MOVE 0,250
930 GCOL 0,0
940 PRINT"AAAAAAAAAA"
950 MOVE 0,250
960 GCOL 0,15
970 INPUT"N2y ";y2
980 IF y2<0 OR y2>1000 THEN 920
990 MOVE 0,200
1000 GCOL 0,0
1010 PRINT"AAAAAAAAAA"
1020 MOVE 0,200
1030 GCOL 0,15
1040 INPUT"N3x ";x3
1050 IF x3<0 OR x3>1000 THEN 990
1060 MOVE 0,150
1070 GCOL 0,0
1080 PRINT"AAAAAAAAAA"
1090 MOVE 0,150
1100 GCOL 0,15
1110 INPUT"N3y ";y3
1120 IF y3<0 OR y3>1000 THEN 1060
1130
1140 contspritepointerx%=0 : REM *** CREATE THE CONTINOUS VARIABLE FOR THE POSITION OF THE PRINTING DOT IN THE SPRITE ***
1150 contspritepointery%=0
1160
1170 spritesizex%=256 : REM *** SET UP THE SPRITE SIZE, THIS IS NOT REALLY NECESSARY FOR THIS DEMO, BUT WOULD ***
1180 spritesizey%=256 : REM *** NEED TO BE PASSED TO A ROUTINE WHEN DIFFERENT SPRITES ARE USED ***
1190
1200 spritepointerx%=0 : REM *** CREATE THE VARIABLES FOR THE EXACT POSITION OF THE DOT BEING PRINTED IN THE ***
1210 spritepointery%=0 : REM *** SPRITE ***
1220
1230 division%=1048576 : REM *** THE NUMBER USED TO MULTIPLY EVERYTHING SO INTERGERS CAN BE USED 100% OF THE TIME ***
1240
1250 PROCtranslate_face
1260 GOTO 470
1270
1280
1290
1300
1310 DEF PROCtranslate_face
1320
1330 scale=1 : REM *** NOT REALLY NEEDED, BUT CAN BE USED TO ENLARGE THE IMAGE PRINTED, BEWARE!!! ***
1340
1350 spritepointerx%=0
1360 spritepointery%=0
1370
1380 p0to1length=(SQR(((x1-x0)*(x1-x0)*division%)+((y1-y0)*(y1-y0)*division%)))DIV1024 : REM *** THE CALCULATIONS USED TO ***
1390 p0to2length=(SQR(((x2-x0)*(x2-x0)*division%)+((y2-y0)*(y2-y0)*division%)))DIV1024 : REM *** CALCULATE THE LENGTH OF ALL ***
1400 p1to3length=(SQR(((x3-x1)*(x3-x1)*division%)+((y3-y1)*(y3-y1)*division%)))DIV1024 : REM *** SIDES OF THE TRANSPOSED ***
1410 p2to3length=(SQR(((x3-x2)*(x3-x2)*division%)+((y3-y2)*(y3-y2)*division%)))DIV1024 : REM *** SPRITE SHAPE ***
1420
1430 IF p0to1length>p2to3length THEN : REM ****************************************
1440 longesthorizontal%=p0to1length : REM * *
1450 ELSE : REM * SORT THE 4 SIDES OF THE RHOMBOID *
1460 longesthorizontal%=p2to3length : REM * TRANSPOSED SHAPE AND PLACE THE VALUE *
1470 ENDIF : REM * INTO THE VARIABLE longestside% *
1480 IF p0to2length>p1to3length THEN : REM * *
1490 longestvertical%=p0to2length : REM ****************************************
1500 ELSE
1510 longestvertical%=p1to3length
1520 ENDIF
1530 IF longestvertical%>longesthorizontal% THEN
1540 longestside%=longestvertical%
1550 ELSE
1560 longestside%=longesthorizontal%
1570 ENDIF
1580
1590
1600
1610 spriteincx%=(spritesizex%*division%)DIVlongestside% : REM *** CALCULATE THE STEP THROUGH THE ORIGIONAL SPRITE (X) ***
1620 spriteincy%=(spritesizey%*division%)DIVlongestside% : REM *** CALCULATE THE STEP THROUGH THE ORIGIONAL SPRITE (Y) ***
1630
2nd half of code in the next post!
Re: 3D Gaming Project
Post by Ric on Feb 17th, 2016, 7:48pm
2nd half
Code: 1640 p0to2incx%=(x2-x0)*division%DIVlongestside% : REM *** CALCULATE THE STEP INN THE SIDE FROM NODES 0 TO 2 (X) ***
1650 p0to2incy%=(y2-y0)*division%DIVlongestside% : REM *** CALCULATE THE STEP INN THE SIDE FROM NODES 0 TO 2 (Y) ***
1660
1670 p1to3incx%=(x3-x1)*division%DIVlongestside% : REM *** CALCULATE THE STEP INN THE SIDE FROM NODES 1 TO 3 (X) ***
1680 p1to3incy%=(y3-y1)*division%DIVlongestside% : REM *** CALCULATE THE STEP INN THE SIDE FROM NODES 1 TO 3 (Y) ***
1690
1700 p0to2fpx%=0 : REM *** SET THE ORIGIN OF NODE 0 TO 0,0 (SIDE N0 TO N2) ***
1710 p0to2fpy%=0
1720
1730 p1to3fpx%=(x1-x0)*division% : REM *** SET THE START POINT OF THE SIDE N1 TO N3 IN RELATION ***
1740 p1to3fpy%=(y1-y0)*division% : REM *** TO N0 ***
1750
1760 REPEAT
1770
1780 linefpx%=p0to2fpx% : REM *** SET THE START POINT OF THE LINE TO BE PRINTED BETWEEN ***
1790 linefpy%=p0to2fpy% : REM *** LINES N0,N2 AND N1,N3 ***
1800
1810 contspritepointerx%=0 : REM *** RESET THE CONTINUOUS POINTER FOR THE SPRITE ***
1820 spritepointerx%=0 : REM *** RESET THE SPRITE POINTER IN THE X PLANE ***
1830
1840 lineincx%=(p1to3fpx%-p0to2fpx%)/longestside% : REM *** CALCULATE THE STEPS BETWEEN LINES N0,N2 TO N1,N3 (X) ***
1850 lineincy%=(p1to3fpy%-p0to2fpy%)/longestside% : REM *** CALCULATE THE STEPS BETWEEN LINES N0,N2 TO N1,N3 (Y) ***
1860
1870
1880 REPEAT
1890
1900 GCOL 0,sprite(spritepointerx%,spritepointery%) : REM *** RETRIEVE COLOUR OF DOT TO BE DRAWN ***
1910 MOVE x0+((linefpx%*scale)DIVdivision%),y0+((linefpy%*scale)DIVdivision%) : REM *** MOVE TO DRAW POINT ***
1920 DRAW x0+((linefpx%*scale)DIVdivision%),y0+((linefpy%*scale)DIVdivision%) : REM *** DRAW DOT ***
1930
1940 linefpx%+=lineincx% : REM *** INCREASE(STEP) THE POSITION OF THE LINE BETWEEN N0,N2 ***
1950 linefpy%+=lineincy% : REM *** AND N1,N3 READY FOR THE PLOTTING OF THE NEXT DOT ***
1960
1970 contspritepointerx%+=spriteincx% : REM *** INCREASE CONTINUOUS POINTER (X) ***
1980 spritepointerx%=contspritepointerx%DIVdivision% : REM *** CALCULATE NEW POINTER POSITION IN ORIGIONAL SPRITE (X)***
1990
2000 UNTIL spritepointerx%>=spritesizex% : REM *** HAS THE SPRITE POINTER EXCEEDED THE SIZE OF THE SPRITE (X) ***
2010
2020 p0to2fpx%+=p0to2incx% : REM *** INCREASE(STEP) THE LINE N0,N2 FOR THE NEXT PRINTED LINE (X) ***
2030 p0to2fpy%+=p0to2incy% : REM *** INCREASE(STEP) THE LINE N0,N2 FOR THE NEXT PRINTED LINE (Y) ***
2040
2050 p1to3fpx%+=p1to3incx% : REM *** INCREASE(STEP) THE LINE N1,N3 FOR THE NEXT PRINTED LINE (X) ***
2060 p1to3fpy%+=p1to3incy% : REM *** INCREASE(STEP) THE LINE N1,N3 FOR THE NEXT PRINTED LINE (Y) ***
2070
2080 contspritepointery%+=spriteincy% : REM *** INCREASE CONTINUOUS POINTER (Y) ***
2090 spritepointery%=contspritepointery%DIVdivision% : REM *** CALCULATE NEW POINTER POSITION IN ORIGIONAL SPRITE (X) ***
2100
2110 UNTIL spritepointery%=>spritesizey% : REM *** HAS THE SPRITE POINTER EXCEEDED THE SIZE OF THE SPRITE (Y) ***
2120
2130 ENDPROC
Hope its annotated enough
Enjoy
Re: 3D Gaming Project
Post by DDRM on Feb 18th, 2016, 08:09am
Hi Ric,
That seems to work nicely, if quite slowly in BASIC - not surprisingly! I'll be interested to see if you can make it fly in assembler.
Of course there are much quicker ways to do this for a chessboard, but I presume it's just a convenient image to analyse, and the ultimate goal would be an image, so you can't just draw triangles.
With regard to your query about the VDU 23 line - what doesn't work? It generates a black square instead of A. You are using it to clear the bit of screen where you are putting your coordinate requests? Wouldn't RECTANGLE FILL be easier?
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on Feb 27th, 2016, 5:16pm
Evening D and others
Just a quck one for Saturday night.
You were right D, the chess board was just a fancy block of colour to transpose and the goal is a coloured image.
Here is the assembler version, and pretty fast it is too. Code: VDU 23,22,1346;674;16,16,16,0
HIMEM=(LOMEM+500000000) AND -4
DIM code% NOTEND AND 2047, code% 6143
DIM data% 2048
DIM temp% 2048
DIM sprite% 1368640
DIM count% 3
FOR I% = 0 TO 2 STEP 2
P% = code%
[
OPT I%
.starttranspose
mov eax, 0 ; }
mov ebx, 0 ; } Clear registers
mov ecx, 0 ; }
mov edx, 0 ; }
mov DWORD [data%+116], 0 ; }
mov DWORD [data%+120], 0 ; }
mov DWORD [data%+124], 0 ; }
mov DWORD [data%+128], 0 ; }
mov eax, [data%+8] ; }
sub eax, [data%] ; } Load Node 1 x in to eax,
mov ebx, eax ; } subtract Node 0 x
mul ebx ; } Put eax in to ebx and miltply.
mov ecx, eax ; } (square eax) And store in ecx.
mov eax, [data%+12] ; }
sub eax, [data%+4] ; } Load Node 1 y in to eax
mov ebx, eax ; } subtract Node 0 y
mul ebx ; } Put eax in to ebx and multiply.
add eax, ecx ; } (square) And add to ecx.
mov ebx, 16384 ; }
mul ebx ; } Multiply ecx by 16384
mov [temp%], eax ; } and place result in [temp]
fild DWORD [temp%] ; }
fsqrt ; } Find squareroot of [temp]
fistp DWORD [temp%] ; }
mov eax, [temp%] ; } Divide the root by 128 to
mov ebx, 128 ; } convert the result to the
mov edx, 0 ; } correct factor.
div ebx ; }
mov [data%+32], eax ; } Store result in [p0to1l]
mov eax, [data%+16] ;
sub eax, [data%] ;
mov ebx, eax ;
mul ebx ;
mov ecx, eax ; Find length between
mov eax, [data%+20] ; Nodes 2 and 0
sub eax, [data%+4] ;
mov ebx, eax ;
mul ebx ;
add eax, ecx ;
mov ebx, 16384 ;
mul ebx ;
mov [temp%], eax ;
fild DWORD [temp%] ;
fsqrt ;
fistp DWORD [temp%] ;
mov eax, [temp%] ;
mov ebx, 128 ;
mov edx, 0 ;
div ebx ;
mov [data%+36], eax ;
mov eax, [data%+24] ;
sub eax, [data%+8] ;
mov ebx, eax ;
mul ebx ;
mov ecx, eax ; Find length between
mov eax, [data%+28] ; Nodes 3 and 1
sub eax, [data%+12] ;
mov ebx, eax ;
mul ebx ;
add eax, ecx ;
mov ebx, 16384 ;
mul ebx ;
mov [temp%], eax ;
fild DWORD [temp%] ;
fsqrt ;
fistp DWORD [temp%] ;
mov eax, [temp%] ;
mov ebx, 128 ;
mov edx, 0 ;
div ebx ;
mov [data%+40], eax ;
mov eax, [data%+24] ;
sub eax, [data%+16] ;
mov ebx, eax ;
mul ebx ;
mov ecx, eax ; Find length between
mov eax, [data%+28] ; Nodes 3 and 2
sub eax, [data%+20] ;
mov ebx, eax ;
mul ebx ;
add eax, ecx ;
mov ebx, 16384 ;
mul ebx ;
mov [temp%], eax ;
fild DWORD [temp%] ;
fsqrt ;
fistp DWORD [temp%] ;
mov eax, [temp%] ;
mov ebx, 128 ;
mov edx, 0 ;
div ebx ;
mov [data%+44], eax ;
mov eax, [data%+44] ;
cmp [data%+32], eax ;
jae higherh ;
mov [data%+48], eax ; Load longest
jmp passa ; horizontal side
.higherh ; in to the register
mov eax, [data%+32] ; [longesthorizontal]
mov [data%+48], eax ;
.passa
mov eax, [data%+40] ;
cmp [data%+36], eax ;
jae higherv ;
mov [data%+52], eax ; Load longest
jmp passb ; vertical side
.higherv ; in to the register
mov eax, [data%+36] ; [longestvertical]
mov [data%+52], eax ;
.passb
mov eax, [data%+52] ;
cmp [data%+48], eax ;
jae highers ; Load longest
jmp passc ; side
.highers ; in to the register
mov eax, [data%+48] ; [longestside]
.passc ;
sal eax, 6 ;
mov ebx, 43
mov edx, 0
div ebx
mov [data%+56], eax ;
mov eax, 16384 ;
mov ebx, [data%+60] ; Calculate the sprite
mul ebx ; step increase in x and
mov ebx, [data%+56] ; store result in [data%+68]
div ebx ;
mov [data%+68], eax ;
mov eax, 16384 ;
mov ebx, [data%+64] ; Calculate the sprite
mul ebx ; step increase in y and
mov ebx, [data%+56] ; store result in [data%+72]
div ebx ;
mov [data%+72], eax ;
mov eax, [data%+16] ;
sub eax, [data%] ;
mov ebx, 16384 ; Calculate step from
mul ebx ; n0 to n2 in x and store
mov ebx, [data%+56] ; in [data%+76]
cmp eax, 0 ;
jl p0to2xnegdiv ;
mov edx, 0 ;
div ebx ;
jmp p0to2xnegpass ;
.p0to2xnegdiv ;
neg eax ; }
mov edx, 0 ; } Produce a negative
div ebx ; } division
neg eax ; }
.p0to2xnegpass ;
mov [data%+76], eax ;
mov eax, [data%+20] ;
sub eax, [data%+4] ;
mov ebx, 16384 ; Calculate step from
mul ebx ; n0 to n2 in y and store
mov ebx, [data%+56] ; in [data%+80]
cmp eax, 0 ;
jl p0to2ynegdiv ;
mov edx, 0 ;
div ebx ;
jmp p0to2ynegpass ;
.p0to2ynegdiv ;
neg eax ; }
mov edx, 0 ; } Produce a negative
div ebx ; } division
neg eax ; }
.p0to2ynegpass ;
mov [data%+80], eax ;
As is now usual the post is in two halves so will need to do some careful pasting.
Ric
Re: 3D Gaming Project
Post by Ric on Feb 27th, 2016, 5:19pm
Code: mov eax, [data%+24] ;
sub eax, [data%+8] ;
mov ebx, 16384 ; Calculate step from
mul ebx ; n1 to n3 in x and store
mov ebx, [data%+56] ; in [data%+84]
cmp eax, 0 ;
jl p1to3xnegdiv ;
mov edx, 0 ;
div ebx ;
jmp p1to3xnegpass ;
.p1to3xnegdiv ;
neg eax ; }
mov edx, 0 ; } Produce a negative
div ebx ; } division
neg eax ; }
.p1to3xnegpass ;
mov [data%+84], eax ;
mov eax, [data%+28] ;
sub eax, [data%+12] ;
mov ebx, 16384 ; Calculate step from
mul ebx ; n1 to n3 in y and store
mov ebx, [data%+56] ; in [data%+88]
cmp eax, 0 ;
jl p1to3ynegdiv ;
mov edx, 0 ;
div ebx ;
jmp p1to3ynegpass ;
.p1to3ynegdiv ;
neg eax ; }
mov edx, 0 ; } Produce a negative
div ebx ; } division
neg eax ; }
.p1to3ynegpass ;
mov [data%+88], eax ;
mov DWORD [data%+92], 0 ; Set start point for p0to2
mov DWORD [data%+96], 0 ; x and y
mov eax, [data%+8] ;
sub eax, [data%] ; Set start point for p1to3
mov ebx, 16384 ; in x
mul ebx ;
mov [data%+100], eax ;
mov eax, [data%+12] ;
sub eax, [data%+4] ; Set start point for p1to3
mov ebx, 16384 ; in y
mul ebx ;
mov [data%+104], eax ;
.startmainloopy
mov eax, [data%+92] ; Set linefpx to p0to2fpx
mov [data%+108], eax ;
mov eax, [data%+96] ; Set linefpy to p0to2fpy
mov [data%+112], eax ;
mov DWORD [data%+116], 0 ; Initialise contspritepointerx
mov DWORD [data%+124], 0 ; Initialise spritepointerx
mov eax, [data%+100] ;
sub eax, [data%+92] ; Calculate lineincx and
mov ebx, [data%+56] ; store in [data%+132]
cmp eax, 0 ;
jl lixnegdiv ;
mov edx, 0 ;
div ebx ;
jmp lixnegpass ;
.lixnegdiv ;
neg eax ; }
mov edx, 0 ; } Produce a negative
div ebx ; } division
neg eax ; }
.lixnegpass ;
mov [data%+132], eax ;
mov eax, [data%+104] ;
sub eax, [data%+96] ; Calculate lineincy and
mov ebx, [data%+56] ; store in [data%+136]
cmp eax, 0 ;
jl liynegdiv ;
mov edx, 0 ;
div ebx ;
jmp liynegpass ;
.liynegdiv ;
neg eax ; }
mov edx, 0 ; } Produce a negative
div ebx ; } division
neg eax ; }
.liynegpass ;
mov [data%+136], eax ;
.startmainloopx
mov ecx, 0
mov edx, 0
mov eax, [data%+108] ;
mov ebx, 16384 ;
cmp eax, 0 ; Calculate x displacement
jl cxdnegdiv ;
mov edx, 0 ;
div ebx ;
jmp cxdnegpass ;
.cxdnegdiv ;
neg eax ; }
mov edx, 0 ; } Produce a negative
div ebx ; } division
neg eax ; }
.cxdnegpass ;
add eax, [data%] ; for next pixel
; INSERT CHECKS HERE AGAINST X DISPLACEMENT OUTSIDE SCREENSIZE
; AND JUMP TO .pixelpass
mov ebx, 4 ;
mul ebx ;
mov ecx, eax ;
mov eax, [data%+112] ;
mov ebx, 16384 ;
cmp eax, 0 ; Calculate y displacement
jl cydnegdiv ;
mov edx, 0 ;
div ebx ;
jmp cydnegpass ;
.cydnegdiv ;
neg eax ; }
mov edx, 0 ; } Produce a negative
div ebx ; } division
neg eax ; }
.cydnegpass ;
add eax, [data%+4] ; for next pixel
; INSERT CHECKS HERE AGAINST Y DISPLACEMENT OUTSIDE SCREENSIZE
; AND JUMP TO .pixelpass
mov ebx, 5384 ;
mul ebx ;
add ecx, eax ; Sum x and y to create offset for bits%
push ecx
mov edx, [data%+124] ; Load edx with spritepointerx
sal edx, 2 ; Multiply by 4
push edx ;
mov eax, [data%+128] ; Load eax with spritepointery
mov ebx, [data%+60] ; Multiply by spritesizex
mul ebx ;
sal eax, 2 ; Multiply by 4 (eax)
pop edx ;
add eax, edx ; Add edx to eax to create offset for sprite%
pop ecx ;
mov edx, [^bits%] ; Create physical position of next
add edx, ecx ; pixel to be printed
mov ebx, sprite% ; Get colour of pixel to be printed
add ebx, eax ; from array sprite%
mov eax, [ebx] ; Print pixel
mov [edx], eax ;
.pixelpass
mov eax, [data%+132] ; Increase linefpx by lineincx
add [data%+108], eax ;
mov eax, [data%+136] ; Increase linefpy by lineincy
add [data%+112], eax ;
mov eax, [data%+68] ; Increase contspritepointerx by
add [data%+116], eax ; spriteincx
mov DWORD [temp%], 16384 ;
fild DWORD [data%+116] ;
fidiv DWORD [temp%] ; Calculate new value for spritepointerx
fistp DWORD [data%+124] ; and place back in [data%+124]
mov eax, [data%+124]
cmp eax, [data%+60]
jb NEAR startmainloopx
mov eax, [data%+76] ; Increment p0to2fpx by p0to2incx
add [data%+92], eax ;
mov eax, [data%+80] ; Increment p0to2fpy by p0to2incy
add [data%+96], eax ;
mov eax, [data%+84] ; Increment p1to3fpx by p1to3incx
add [data%+100], eax ;
mov eax, [data%+88] ; Increment p1to3fpy by p1to3incy
add [data%+104], eax ;
mov eax, [data%+72] ; Increment contspritepointery
add [data%+120], eax ; by spriteincy
mov ecx, 0
mov edx, 0
mov eax, [data%+120] ;
mov ebx, 16384 ; Calculate new value of spritepointery
div ebx ; and place back in [data%+128]
mov edx, 0 ;
mov [data%+128], eax ;
mov eax, [data%+128]
cmp eax, [data%+64]
jb NEAR startmainloopy
ret
]
NEXT I%
ok, may be three posts!!!!!!!!!!
Re: 3D Gaming Project
Post by Ric on Feb 27th, 2016, 5:26pm
Post three!!
Code: DIM BITMAPINFOHEADER{Size%, Width%, Height%, Planes{l&,h&}, BitCount{l&,h&}, Compression%, SizeImage%, XPelsPerMeter%, YPelsPerMeter%, ClrUsed%, ClrImportant%}
DIM bmi{Header{} = BITMAPINFOHEADER{}}
bmi.Header.Size% = DIM(BITMAPINFOHEADER{})
bmi.Header.Width% = 1346
bmi.Header.Height% = 674
bmi.Header.Planes.l& = 1
bmi.Header.BitCount.l& = 32
SYS "CreateDIBSection", @memhdc%, bmi{}, 0, ^bits%, 0, 0 TO hbitmap%
IF hbitmap%=0 ERROR 100, "Couldn't create DIBSection"
SYS "SelectObject", @memhdc%, hbitmap% TO oldhbm%
SYS "DeleteObject", oldhbm%
SYS "InvalidateRect", @hwnd%, 0, 0
FOR x=0 TO 7
FOR y=0 TO 7
IF (x MOD 2=1 AND y MOD 2=1) OR (x MOD 2=0 AND y MOD 2=0) THEN
FOR xloop=0 TO 31
FOR yloop=0 TO 31
?(sprite%+(((x*128)+(xloop*4))+((((y*32)+yloop)*1024))))=255
?(sprite%+(((x*128)+(xloop*4))+((((y*32)+yloop)*1024))+1))=0
?(sprite%+(((x*128)+(xloop*4))+((((y*32)+yloop)*1024))+2))=0
?(sprite%+(((x*128)+(xloop*4))+((((y*32)+yloop)*1024))+3))=0
NEXT
NEXT
ELSE
FOR xloop=0 TO 31
FOR yloop=0 TO 31
?(sprite%+(((x*128)+(xloop*4))+((((y*32)+yloop)*1024))))=0
?(sprite%+(((x*128)+(xloop*4))+((((y*32)+yloop)*1024))+1))=255
?(sprite%+(((x*128)+(xloop*4))+((((y*32)+yloop)*1024))+2))=0
?(sprite%+(((x*128)+(xloop*4))+((((y*32)+yloop)*1024))+3))=0
NEXT
NEXT
ENDIF
NEXT
NEXT
REPEAT
?(data%+61)=1
?(data%+65)=1
CLS
SYS "InvalidateRect", @hwnd%, 0, 0
PRINT"The origional tile being transfered is a chessboard, 256x256 pixels."
PRINT"Choose the coordinates for nodes 0,1,2 and 3 and watch"
PRINT""
PRINT"Max distance between nodes is 350 point to point!!!!!!"
PRINT""
PRINT"Node order is N2 N3"
PRINT""
PRINT""
PRINT""
PRINT" N0 N1"
FOR loop=0 TO 3
PRINTTAB(0,10+(loop*2))"Nx";loop
INPUTTAB(4,10+(loop*2))"";nodex
?(data%+(loop*8))=nodex MOD 256
?(data%+(loop*8+1))=nodex DIV 256
PRINTTAB(0,10+(loop*2)+1)"Ny";loop
INPUTTAB(4,10+(loop*2)+1)"";nodey
?(data%+(loop*8+4))=nodey MOD 256
?(data%+(loop*8+5))=nodey DIV 256
NEXT
TIME=0
CALL starttranspose
SYS "InvalidateRect", @hwnd%, 0, 0
PRINT "Time taken : ";TIME
PRINTTAB(30,40)"Press any key to do it again"
Key%=0
*FX 15,1
REPEAT
Key%=INKEY(100)
UNTIL Key%<>-1
UNTIL FALSE
REM data nodex0
REM data+4 nodey0
REM data+8 nodex1
REM data+12 nodey1
REM data+16 nodex2
REM data+20 nodey2
REM data+24 nodex3
REM data+28 nodey3
REM data+32 p0to1length
REM data+36 p0to2length
REM data+40 p1to3length
REM data+44 p2to3length
REM data+48 longesthorizontal
REM data+52 longestvertical
REM data+56 longestside
REM data+60 spritesizex
REM data+64 spritesizey
REM data+68 spriteincx
REM data+72 spriteincy
REM data+76 p0to2incx
REM data+80 p0to2incy
REM data+84 p1to3incx
REM data+88 p1to3incy
REM data+92 p0to2fpx
REM data+96 p0to2fpy
REM data+100 p1to3fpx
REM data+104 p1to3fpy
REM data+108 linefpx
REM data+112 linefpy
REM data+116 contspritepointerx
REM data+120 contspritepointery
REM data+124 spritepointerx
REM data+128 spritepointery
REM data+132 lineincx
REM data+136 lineincy
The sprite to be printed is in full 32bit colour and would benefit from a photo etc to really try it out. Does anyone know if you can openin#x a .bmp etc so I can easily import a picture?
Ric
Re: 3D Gaming Project
Post by DDRM on Mar 1st, 2016, 08:14am
Hi Ric,
That looks pretty impressive! If you can really redraw it in one centisecond that gives you quite a bit in hand to actually run the game.
Loading bitmaps: yes, several options. You can use:
*LOAD to load a file to a memory address (you would need to reserve enough space first)
*DISPLAY will load a bitmap file and stick it on the screen - I suspect you may be able to use that to load the image into a DIBSection you could manipulate, but I don't offhand know if you could do that without it appearing on the display - my guess is that it will get loaded into whatever bitmap is selected to the BB4W device context. You might be able to do it by
doing *REFRESH OFF,
selecting the DIBSection into the device context
*DISPLAYing your picture
Deselecting it and reselecting the default display bitmap
In the manual, under "displaying GIF and JPEG images", there is a more general routine for loading an image. If you look at the line
SYS !(!gpp%+32), ....
You will see you specify a device context to render to: in this case memhdc%. I suspect if you had another device context with your DIBSection you could specify that here, and thus be able to load a wide range of picture types to it, to work on "offscreen". Note that that call also appears to allow you to scale the input image to output bitmap (or part of it).
Hope that's helpful. If David Williams is still reading, he might have better ideas.
D
Re: 3D Gaming Project
Post by Ric on Mar 1st, 2016, 5:59pm
Thanks D
I will look into the *DISPLAY method as that would enable a straight edit on the screen.
With regards to the speed of the assembler routine, I have calculated that in order to fill the whole screen I can only refresh about 10fps without any gaming instructions. Really this needs to be upwards of 40fps for HD games so a faster routine is required, I am working on floating point calculations, but never done before so may be a while.
Re: 3D Gaming Project
Post by Ric on Mar 23rd, 2016, 09:01am
Thanks for the hint D, I now have a picture of my son rotating on the cube. The routine to print the sprites is now a combination of asm and fpasm. With no gaming code yet it will run at approx. 55fps. Not bad but I was hoping for more. It is now to big to add here as a code snippet (approx 40000 chars) so I will look for another method of distribution.
Re: 3D Gaming Project
Post by michael on Mar 23rd, 2016, 9:50pm
DDRM would know how the following technique could be done in BBC basic, or perhaps Richard would know.
1) offset a secondary window for the size of image you want to create
2) capture the image in a sprite
3) post the sprite on the main display window
4) clear the offset window and repeat
This would create flicker free animation and would allow redraws to be done off screen
Also, this would minimize memory use because you are using the same sprite for image capture/ transfer/ display
Re: 3D Gaming Project
Post by Ric on Mar 24th, 2016, 5:20pm
Thanks Michael,
I am sure for a man moving across the screen that would work, but the 55fps is for the whole screen rendering a 3d landscape like most modern games. My calculations work out that this will drop to 40fps with game play code. The sprite in question is just one of many used to create the landscape, and using the four corners as nodes can be skewed to create full 3d with depth perception. Originally my challenge to myself was to learn asm and write a 3d game, it's going OK so far. If I moved to a modern laptop this would aid speed as mine currently is a measly 1.9Ghz.
Regards Ric
Re: 3D Gaming Project
Post by Ric on Apr 24th, 2016, 9:12pm
If anyone is still following this link, this is wherein am up to.
https://youtu.be/G-qFv_-0W3Y
Re: 3D Gaming Project
Post by Wildmooer on May 2nd, 2016, 2:33pm
Thank you. I've been reading!
Re: 3D Gaming Project
Post by Ric on May 3rd, 2016, 9:27pm
I think I have found an easy way to post code by using Wikisend, if it works I will post the code so far. The ball now has a globe skin on it.
Ric
Re: 3D Gaming Project
Post by michael on May 3rd, 2016, 10:21pm
That's pretty cool. You able to place more objects on the screen and put them at depth?
Re: 3D Gaming Project
Post by Wildmooer on May 4th, 2016, 12:38am
on Apr 24th, 2016, 9:12pm, Ric wrote:
Cool! I'd really like to see the code. I'm new to this and my 3D is still very crude.
Re: 3D Gaming Project
Post by Ric on May 5th, 2016, 12:03pm
I can not yet put multiple objects but that is only because I have only loaded the nodes for one. The depth I am working on, it is a simple calculation involving the z vector and then factor X and y. I will post on Wikisend tonight.
Re: 3D Gaming Project
Post by Ric on May 5th, 2016, 7:57pm
Evening all. I was going to post the code on wikisend, but I cannot get the upload to work. I have given in!!! If anyone can tell me how to post the code some how, somewhere I will do so. Or I can email it.
Ric
Re: 3D Gaming Project
Post by DDRM on May 6th, 2016, 08:23am
Hi Ric,
I've never used Wikisend, but might Github be a suitable option? I've used that in association with a MOOC course I did, and it seemed OK.
https://github.com/
I think the Wiggio forum and its file storage are still functional: you'll need to sign up to upload, but it's free:
https://wiggio.com/
Richard has now set up what looks something like a mirror of the old Yahoo forum on Groups.io:
https://groups.io/g/bb4w
I haven't really got to grips with that forum yet, but it looks like once you have signed in you have access to a file storage area, though my guess is that that would only be accessible to others who were members.
I'd certainly be interested to see what you've done - both in terms of code and function.
Best wishes,
D
Re: 3D Gaming Project
Post by DDRM on May 6th, 2016, 08:28am
on May 4th, 2016, 12:38am, Wildmooer wrote:Cool! I'd really like to see the code. I'm new to this and my 3D is still very crude. |
|
Hi Wildmooer,
If you are relatively new to programming you may find Ric's code a bit intimidating - most of it is in assembler, I think!
It might be worth playing with the Direct3D library supplied with with BB4W -even that is tricky, but simple things (like a mapped rotating sphere!) are relatively straightforward - indeed a working demo is supplied (world.bbc, in the graphics folder of the examples).
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on May 6th, 2016, 11:59am
Cheers D
I will have a look at these tonight.
You are correct in assuming most of the code is in assembler, with only the setting of parameters in basic. I have loosely annotated it , but even so unless you are very au fait with assembler it will look like gobbledegook😋
Ric
Re: 3D Gaming Project
Post by Ric on May 6th, 2016, 7:07pm
Hello again,
I have had a go at all the suggested methods of uploading my code, but without sounding to negative I feel like a blind man playing snooker. I have failed with every attempt. And I am thoroughly brassed off. I will keep updating where I am up to and post results via video on youtube. but unless someone is prepared to ring me up and walk me through some form of file sharing I am giving up. Sorry to those who are following, but I really cant get any of the methods to work.
Ric
Re: 3D Gaming Project
Post by michael on May 6th, 2016, 11:26pm
Dropbox is supposedly very good. And it has some high profile programmers behind it.
Actually Richard was the one to recommend it to me so here is the link:
https://www.dropbox.com/
I have it but have no major projects done to use it yet.
Re: 3D Gaming Project
Post by Wildmooer on May 8th, 2016, 5:06pm
Thank you for the advice. I'll try to understand the 3D library... if I'm able!
Re: 3D Gaming Project
Post by Ric on May 18th, 2016, 8:11pm
Latest update
I have now got to a point where I can transpose a picture on to the 3d shape.
Also I think I have found a way to upload the code. If this works do not to hard to break shape II, it has very few error checkers in the basic code.
I would suggest 120 faces and radius of 200 to start.
Hopefully these links will get you to the files (you may have to register for pCloud)
https://my.pcloud.com/publink/show?code=XZ262mZySqsUb9LH608Gww9JTQE0LffWyPy
https://my.pcloud.com/publink/show?code=XZj62mZSB4pTArNQrHxz6VjRHWh70fHIukV
Both files need to be in the same folder to run.
Let me know how you get on 
Ric
Re: 3D Gaming Project
Post by David Williams on May 18th, 2016, 8:24pm
I downloaded the two files easily without any problems (no registration required), and the program ran beautifully on my Core i7. Nice bit of code, in a nice clear style!
David.
--
Re: 3D Gaming Project
Post by Ric on May 19th, 2016, 5:13pm
Nice to see an old dog (that would be me) can be taught new tricks
. Could you let me know how many frames per second it runs at on your corei7 please David. Could you run a test on shape 1 with 120 faces and a radius of 200. I have an old lap top and it runs about 27 fps. I am interested to see what can be produced on a modern spec machine.
Many thanks
Ric
Re: 3D Gaming Project
Post by Ric on May 19th, 2016, 5:20pm
Sorry I forgot to say,
The code runs for any configuration of sides as long as they all have four nodes, my next step is to design a package to enable the construction of such objects, my son would love to see a dinosaur! But more likely an inanimate object like a car.
may take a few weeks as I am limited to a few hours coding a week, but I am keeping the dream of a 3d game alive.
Ric
Re: 3D Gaming Project
Post by David Williams on May 19th, 2016, 7:56pm
on May 19th, 2016, 5:13pm, Ric wrote:Nice to see an old dog (that would be me) can be taught new tricks . Could you let me know how many frames per second it runs at on your corei7 please David. Could you run a test on shape 1 with 120 faces and a radius of 200. I have an old lap top and it runs about 27 fps. I am interested to see what can be produced on a modern spec machine. |
|
I get 72 fps.
I don't actually have very good graphics hardware (integrated graphics - Intel HD Graphics 4600, rather than separate graphics card). Of course, in the case of your program, it's the CPU that's doing the rendering anyway so a high-end graphics card is unlikely to make any difference to the frame rate. I'm using a Core i7-4790 @ 3.60 GHz.
David.
--
Re: 3D Gaming Project
Post by Ric on May 19th, 2016, 9:29pm
Thanks David
72 is quite impressive.
The goal I set myself was to write a 3d game using BBC Basic (including Assembler) without using any libraries or add-ons. If I succeed and it runs at an acceptable frame speed I will then move on to the graphics card and openGL, but for now all is good.
Ric
ps. I might make the routines into their own library for others to use.
Re: 3D Gaming Project
Post by Ric on May 26th, 2016, 10:36pm
Evening,
I was going to start a design package to help develop 3D objects, but there was one thing missing from the current project. Interpolation. Here is he link to the improved routine.
https://my.pcloud.com/publink/show?code=XZKQvmZBr2Er3lU0wYDDMLo5twkzpU53LhX
Have a play with the number of "shadepolations" and see what you think. Try a low number of faces(20) and high interpolation (even 2 CALLs has a good result).
Could some one have a go at shape 1, 90 faces, 200 diameter and 2 then 3 shadepolation CALLs, and let me know the fps and the machine you are running on.
This new routine now shades the whole screen in anticipation of multiple objects so I am expecting it to be slower than last time.
Thanks Ric
Re: 3D Gaming Project
Post by sveinioslo on Jun 3rd, 2016, 07:19am
Nice work !
shape 1, 90 faces, 200 diameter 2 shadepolation CALLs = 92 fps.
shape 1, 90 faces, 200 diameter 3 shadepolation CALLs = 86 fps.
Laptop, 64 bit windows 10, Core i7 4720 2.6 GHz.
Svein
Re: 3D Gaming Project
Post by Ric on Jun 4th, 2016, 12:53pm
Thanks Svein,
I noticed in your thread, 256 thread png you have code that appears to run multiple threads at the same time. Have I read this correctly? If so I would be very interested in your opinions about moving my project on to encompass the technique.
Regards
Ric
Re: 3D Gaming Project
Post by Ric on Jun 8th, 2016, 9:13pm
Here is the latest update.
It is one for Michael
, it has two objects and depth
https://my.pcloud.com/publink/show?code=XZgaqbZhR9P9v2qUByqkng2XcsCg7oSCIp7
Ric
PS I am now working on the design package to create complex shapes.
Re: 3D Gaming Project
Post by DDRM on Jun 9th, 2016, 08:44am
Hi Ric,
That's coming along well - I get 138 fps, which gives you quite a bit in hand for all the other scene elements and the game engine...
...you'll have a custom implementation of Direct3D soon...

D
Re: 3D Gaming Project
Post by Ric on Jun 9th, 2016, 3:47pm
Ha Ha, Cheers D,
Should be easier to use
Re: 3D Gaming Project
Post by Ric on Jun 19th, 2016, 10:35pm
Here is the latest incarnation.
The two objects are now truly independent and any number can now be produced, laborious to set up and a design package will be the next stop. I have said that before, but this time I think I mean it?
When running the program the keys
Z rotates anticlockwise from above
X rotates clockwise from above
' rotates up
/ rotates down
and spacebar exits to BASIC control
https://my.pcloud.com/publink/show?code=XZEp9hZYDnEkKPF3MRtLkVFo6uyI5b4pbky
Re: 3D Gaming Project
Post by michael on Jun 20th, 2016, 01:38am
That's pretty impressive. Now you got me determined to get my example done..
( some people may say its cheating, but I really think that the first DOOM game was made the same way as I am doing my 3D.. Especially since the technology for imaging has been around since the 80s.)
And probably everyone will agree with my strategy and then we can make a game and link it on Richards forum in executable form and when he runs it he will be fooled into thinking that we cracked the 3D world.
But then he probably has a way of figuring out that it was done with 3D image trickery.
Of course if he remembers email concerning my plans, he may just figure it out and respond.. But I will not say what it was unless he figures it out.
Also a mention I didn't post my advancement in ASM after Richard had helped with the memory allocation, but I did advance. Here is where I landed with ASM so far.
( controlling graphics would be the end game, but the next task would be to do multiple variable compares and multiple condition jumps.)
Code:
PRINT "Please wait for increment to 2 million"
PROCassemble
bcd%=2000000
bin%=0
REM REPEAT
CALL bin2bcd
REM UNTIL bin%=2000000
PRINT bin%
PRINT "DONE"
END
DEF PROCassemble
LOCAL P%, L%, gap%
DIM gap% &7FF, P% &7FF, L% &7FF
[OPT 10
.bin2bcd
mov eax,[^bin%]
mov ebx,[^bcd%]
.loop
inc eax
cmp eax,ebx
jle loop
mov [^bin%],eax
ret
]
ENDPROC
Re: 3D Gaming Project
Post by Ric on Jun 20th, 2016, 07:05am
Morning Michael,
You will have to help me a little, I have had no contact with computer games for 30 years, What is Doom? I have seen some posters, but know no more.
Your loop does what it says it counts to 2000001 and stops.
What do you need help with?
If you want it to stop at 2000000 change the jle loop to jne loop. This will keep looping while bin% and bcd% are not equal.
The variables you have used imply you want to turn binary in to binary coded decimal?
Try this code
Code: DIM code% 200 : REM always reserve too much
DIM test 100 : REM reserve memory for variables (the assembler routine used here only needs 12 bytes, memory is cheap, reserve too much)
!test=0 : REM make memory location (32bit dword startimg at test) equal 0
!(test+4)=2000000 : REM make memory location (32bit dword startimg at test+4) equal 2000000 (The +4 is in bytes ie 32bits displacement)
FOR I% = 0 TO 3 STEP 3
P% = code%
[
opt I%
.start
mov eax, [test] ; REM moves the number stored in memory location test to eax
mov ebx, [test+4] ; REM moves the number stored in memory location test+4 to eax
.loop
inc eax
cmp eax, ebx
jne loop ; REM repeats until they are equal
mov [test+8], eax ; REM stores eax in memory location test+8
ret
]
NEXT I%
CALL start
PRINT "Done ";!(test+8)
There is really elegant way using the ecx register if all you want to do is create a loop.
Ric
Re: 3D Gaming Project
Post by michael on Jun 20th, 2016, 1:44pm
Here is a vid of the version of DOOM I am speaking of
https://www.youtube.com/watch?v=PEbLOnvCckA
Re: 3D Gaming Project
Post by Ric on Jun 20th, 2016, 4:25pm
Can't see a reason why that's not achievable. The routines I am developing are to display true colour sprites in HD. So even if we can't get the initial speed, to replicate the graphics in that demo we could simply change the density to increase speed.
Did the code help or are you further on by now?
Ric
Re: 3D Gaming Project
Post by michael on Jun 20th, 2016, 5:15pm
I guess the next question would be:
What if I wanted to create more than one condition?
The idea being that I might want to check more than one set of values or boundaries.
This is just one condition and one result label:
cmp eax, ebx
jne loop
And I may be jumping a bit too high on this, but what about controlling the location of an object (pointer or even a sprite) or say drawing in assembly?
(seems to be the holy grail according to Richard, as he voiced his feelings about that on his forum)
But I would like to know that also.
Oh and how much memory can I reserve and how does that apply to huge information ?
Code: DIM code% 200 : REM always reserve too much
DIM test 100 : REM reserve memory for variables (the assembler routine used here only needs 12 bytes, memory is cheap, reserve too much)
!test=0 : REM make memory location (32bit dword startimg at test) equal 0
!(test+4)=2000000 : REM make memory location (32bit dword startimg at test+4) equal 2000000 (The +4 is in bytes ie 32bits displacement)
FOR I% = 0 TO 3 STEP 3
P% = code%
[
opt I%
Re: 3D Gaming Project
Post by Ric on Jun 20th, 2016, 5:31pm
If you think of asm as really simple BASIC, this will probably help your understanding. If you want to test more conditions you simply load the test condition and sample it again and then use another branch, sorry jump.
In essence cmp sets the flags and all the operands beginning with j are IF statements with a THEN condition.
I am out for the evening but will send you the PDF of the asm code I used to reference each oppose.
Ric
Re: 3D Gaming Project
Post by Ric on Jun 22nd, 2016, 9:32pm
Michael,
This is the reference I used
http://www.gabrielececchetti.it/Teaching/CalcolatoriElettronici/Docs/i8086_instruction_set.pdf
Also look up simply fpu
Ric
Re: 3D Gaming Project
Post by michael on Jun 24th, 2016, 02:21am
Thanks. I will study this.
Re: 3D Gaming Project
Post by David Williams on Jun 24th, 2016, 04:23am
One idea that could save you a great deal of time, energy and potentially stress (!), is to write speed-critical code in C (or C++), compile it as a DLL and load it into your BB4W as a library, or have the C compiler generate the assembler code. Now, I realise there's an argument as to whether C compilers generate better quality (or more optimal) code than you can with hand-crafted assembly language, but often the C compiler will produce better code because it knows how to sequence (or pipeline) machine code instructions for more efficient execution (fewer stalls, etc.). What you can achieve in a few lines of C in just a few minutes can potentially take hours with assembler code (most of that time debugging), even for relatively experienced Asm coders. Some of my C-coded graphics routines (often written in the space of a few minutes!) are actually faster than their hand-coded Asm equivalents, and that's probably down to better register usage and better pipelining by the C compiler. I learnt the rudiments of C in a few days, so if I can do it.... then so can anyone! BB4W, assembly language and C (via DLLs or assembler code dumps) is such a pleasant and powerful combination.
Check out this program which includes assembly language generated by the GCC C compiler. I remember being very pleased with its efficiency:
http://bb4w.conforums.com/index.cgi?board=assembler&action=display&num=1407003986
I recently renewed my interest in learning C, specifically for the purpose of creating DLLs to be loaded into BB4W, and generating assembly language dumps. It will save so much time and hassle.
David.
--
Re: 3D Gaming Project
Post by michael on Jun 24th, 2016, 04:40am
Nice code link. I will study that.
Re: 3D Gaming Project
Post by Ric on Aug 9th, 2016, 8:53pm
Evening all, its been a long time since the last update, but babies do that to you. If you download this link :-
https://my.pcloud.com/publink/show?code=XZDWdfZJHmqlabpYsbdSKECmqxqIXvQXGoX
it should be the first stages of a 3D design package for BB4W.
Have a play and any feed back would be greatly appreciated.
The only menu driven item that works is:-
Add Object > Quick > 

The rotation is about the screen axis at the moment and this means that if you do not reverse the steps of each rotation then if you get back to x=0 y=0 z=0 then this might not be the true start position. I will sort the rotation later.
If you left click on the centre node of an object and hold it can be moved in the screen xy plane if you right click on the centre node then the object becomes the centre of focus. Left click on the node again to release it.
Happy playing
Ric.
Re: 3D Gaming Project
Post by michael on Aug 10th, 2016, 10:15am
Awesome work
Re: 3D Gaming Project
Post by DDRM on Aug 15th, 2016, 3:51pm
Hi Ric,
That's very impressive!
I like the way you can select and manipulate a single object independently by right-clicking it. Would it be nice to change the top slider from moving the whole view nearer/further, and use it to change the absolute size of the object in this mode?
Presumably in due course we will be able to change the colour of the predefined objects, and to save them as a custom graphics file of some kind?
There's a typo in your title... 
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on Aug 16th, 2016, 4:56pm
That's a good idea, shouldn't be to difficult to implement. I have the colour version ready to go apart from node highlighting. Will post it tonight.
Re: 3D Gaming Project
Post by Ric on Aug 16th, 2016, 9:53pm
Think this is the right link
https://my.pcloud.com/publink/show?code=XZgQhBZhxyjJqO6P0S7EPox287RuXaty1EX
Try solid and line, check in box does not work yet I know.
I have started to implement object scaling with top slider, it does not work yet!
Sorted typo DDRM
Re: 3D Gaming Project
Post by DDRM on Aug 17th, 2016, 09:40am
Hi Ric,
That's coming along nicely - once I worked out that I now had to release the individual components using the button in the characteristics box (after saving!). Your code may be quick, but I am slow...
Are the nets for the individual components stored as an array? If the centre of the object is at (0,0,0) then scaling should be a simple matrix multiplication, but otherwise you may need a multiplication plus an offset.
Getting more demanding, would it be possible to make the sliders usable for both the individual component or the composite at the same time? It would be useful to be able to rotate the assembly to check on 3d positioning of each component as you add it. I wondered about using shift, for example. I can see that there's an issue that the slider would keep moving about... Alternatively, put a separate set of sliders on the characteristics box to move/scale the component?
Will it be possible to select and move individual nodes (and/or groups of nodes) of objects, so we can, for example modify a standard cube into a rhombus, or something?
I assume object 1 is the grid, which makes sense from your point of view, but feels a bit counterintuitive to the user. (I presume it won't form part of the final object you save). Could the display show "object 1" for my first added object, even if behind the scenes it's object(2)?
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on Aug 17th, 2016, 9:41pm
Evening DDRM,
Thanks for the feedback.
I will have a look at the sliders, but it could get rotationally very complicated to do everything live, without saving inbetween, never say die tho'.
The node movement is next on the list of things to do along with being able to disable the grid.
I agree about the object numbers and have made the necessary adjustment.
Next post will be a while, free time has run out again😁
Ric
Re: 3D Gaming Project
Post by Ric on Sep 3rd, 2016, 7:51pm
Hello again,
This is where I am up to so far. The axis' are displayed for demonstration purposes to allow me to develop the software. Currently they are executed using BASIC DRAW commands and thus print over the top of the graphics and are not confined to the window but this will change and they will become useful. The rotation of the objects is now around arbitory axis' and you can rotate the grid while focusing on an object. Where the node option boxes are mis-aligned, just try them, they may or may not work.
https://my.pcloud.com/publink/show?code=XZ1OpWZDFb0vnaaMD0054m1yf7Ffj2hEaYV
Ric
Re: 3D Gaming Project
Post by michael on Sep 4th, 2016, 04:24am
On your previous (Nodes) II the sliders were all working properly. On this latest link, it seems like most the sliders are not responding and those that do, do only at times..
I have an idea, that I am trying to work out the technicalities concerning design. Its a matter of brain storming.
The thought of small game parts. Universal, that we could make.. They would be a sort of real 3D, and actually manipulated by sprites for size.
So for instance we could make sets of eyes and ears on different angles. Not like before. I have some ideas of cropped motion capture of vehicles and other real world objects to make overhead views and rear and side views.
Spy hunter anyone?
Just throwing ideas. I am working on some code art now and will show them using BMPtoCODE.
(by the way I am thinking of making a BBC Basic version of BMPtoCODE. even though I don't really need to.
I keep thinking of how a person could store the perspective views in an array instead of a sprite.
BMPtoARRAYS? Hmmmm...
The thing with arrays is, to make it fast, I would have to eliminate compression. or invent a new smart overlay system that can absorb the image data and read it fast and efficiently. So you would only create the images you needed, and the active parts would only become active depending on say a model's stance, and the different parts would be only called upon to change when the perspective or stance changed..
You know what I mean?
Re: 3D Gaming Project
Post by Ric on Sep 4th, 2016, 09:24am
Michael, when you say don't respond, can you be more specific please, they all work ok on my laptop. the inner four sliders only work when an object is selected by using right mouse button on the object centre node.
Has anyone else had the same problems as Michael?
Ric
Re: 3D Gaming Project
Post by Ric on Sep 4th, 2016, 09:30am
On a separate note, creating bmp to arrays could incur massive memory usage even if the components for each object are small and multifunctional. I don't see why it could not work tho. To move objects over each other you simply store the screen pixels(where you want to print your sprite) in an array print your sprite and when you move the sprite put the screen pixels back.
Ric
Re: 3D Gaming Project
Post by michael on Sep 4th, 2016, 2:18pm
Oh! I got it to work. I am surprised that you actually made it so I could interact directly with the mouse in center. Very nice work.. only once slider on each side works far as I can tell. But that's all that's needed.
As for the arrays, anything with a value of 0 (black would not be plotted, so the image could be plotted fast.
I am still thinking that compression might be needed to keep the arrays small. BMPtoCODE is actually fairly fast. And all your image data is within the program itself instead of an array.
(I can make the black color not plot, and that would make it faster and overlay)
Although using that approach, I would need to clear and redraw the scene every time animation frame changes.
* REFRESH
Here is an example of what BMPtoCODE can do,
Code: VDU 22,8
VDU 23,23,1|
OFF:VDU 5:COLOUR 0:CLG
PROC_image(100,500)
WAIT 0:END
DEF PROC_image(h,v)
u=0:r=0:g=0:b=0:a=0:c=0:t=0
ost$=""
READ x,y:REPEAT
READ nst$,t
IF nst$="0" THEN r=0:g=0:b=0 :REM 'black 0 0 0
IF nst$="1" THEN r=192:g=128:b=64:REM ' brown 192 128 64
IF nst$="2" THEN r=64:g=64:b=192 :REM'dark blue 64 64 192
IF nst$="3" THEN r=128:g=128:b=128:REM' dark grey 128 128 128
IF nst$="4" THEN r=128:g=0:b=0:REM'dark red 128 0 0
IF nst$="5" THEN r=224:g=192:b=0 :REM'dark yellow 224 192 0
IF nst$="6" THEN r=128:g=160:b=192:REM'flat blue 128 160 192
IF nst$="7" THEN r=32:g=192:b=64 :REM'green 32 192 64
IF nst$="8" THEN r=166:g=202:b=240:REM'light blue 166 202 240
IF nst$="9" THEN r=192:g=192:b=192:REM 'light gray 192 192 192
IF nst$="a" THEN r=192:g=224:b=0:REM 'light green 192 224 0
IF nst$="b" THEN r=224:g=32:b=64:REM'light red 224 32 64
IF nst$="c" THEN r=0:g=160:b=192 :REM'medblue 0 160 192
IF nst$="d" THEN r=224:g=128:b=64 :REM 'orange 224 128 64
IF nst$="e" THEN r=224:g=160:b=192:REM'pink 224 160 192
IF nst$="f" THEN r=160:g=64:b=192:REM'purple 160 64 192
IF nst$="g" THEN r=192:g=220:b=192:REM'tan 192 220 192
IF nst$="h" THEN r=255:g=255:b=255:REM'white 255 255 255
IF nst$="i" THEN r=255:g=255:b=0:REM'yellow 255 255 0
COLOUR 0,r,g,b:GCOL 0
FOR u=0 TO t
a=a+1: MOVE h+c,v-a:DRAW h+c,v-a:IF a>x THEN c=c+1:a=0
NEXT u
UNTIL nst$="100000"
MOVE 0,0:ENDPROC
DATA 79,79
DATA 0,595,b,9,0,65,b,17,0,57,b,25,0,51,b,29,0,48,b,31,0,45,b,12,0,9,b,12,0,42,b,10,0,16,b,10,0,38,b,9,0
DATA 21,b,9,0,36,b,8,0,25,b,8,0,34,b,7,0,29,b,7,0,32,b,7,0,32,b,6,0,30,b,6,0,35,b,6,0,28,b,6,0,37
DATA b,6,0,27,b,5,0,39,b,6,0,25,b,5,0,41,b,5,0,24,b,5,0,28,i,3,0,10,b,5,0,23,b,5,0,28,i,4,0,10,b
DATA 5,0,21,b,5,0,29,i,4,0,10,b,5,0,20,b,5,0,30,i,5,0,10,b,5,0,19,b,5,0,12,i,2,0,15,i,5,0,9,b,5
DATA 0,18,b,5,0,11,i,6,0,14,i,4,0,10,b,5,0,17,b,5,0,11,i,7,0,13,i,5,0,9,b,5,0,17,b,4,0,12,i,7,0
DATA 14,i,4,0,10,b,4,0,17,b,4,0,12,i,7,0,15,i,4,0,9,b,4,0,16,b,5,0,12,i,5,0,17,i,4,0,10,b,4,0,15
DATA b,4,0,37,i,4,0,10,b,4,0,15,b,4,0,37,i,4,0,10,b,4,0,15,b,4,0,38,i,4,0,9,b,4,0,14,b,4,0,39,i
DATA 4,0,10,b,4,0,13,b,4,0,39,i,4,0,10,b,4,0,13,b,4,0,39,i,4,0,10,b,4,0,13,b,4,0,39,i,4,0,10,b,4
DATA 0,13,b,4,0,39,i,4,0,10,b,4,0,13,b,4,0,39,i,5,0,9,b,4,0,13,b,4,0,39,i,5,0,9,b,4,0,13,b,4,0
DATA 39,i,5,0,9,b,4,0,13,b,4,0,39,i,4,0,10,b,4,0,13,b,4,0,39,i,4,0,10,b,4,0,14,b,4,0,38,i,4,0,9
DATA b,4,0,15,b,4,0,16,i,2,0,17,i,5,0,9,b,4,0,15,b,4,0,15,i,4,0,16,i,4,0,10,b,4,0,15,b,4,0,14,i
DATA 6,0,15,i,4,0,10,b,4,0,16,b,4,0,12,i,7,0,14,i,5,0,9,b,5,0,16,b,4,0,12,i,7,0,14,i,4,0,10,b,4
DATA 0,17,b,5,0,12,i,5,0,15,i,3,0,10,b,5,0,17,b,5,0,33,i,4,0,10,b,5,0,18,b,5,0,31,i,5,0,9,b,5,0
DATA 19,b,5,0,30,i,4,0,11,b,5,0,20,b,5,0,29,i,3,0,11,b,5,0,22,b,4,0,29,i,2,0,12,b,5,0,22,b,5,0,43
DATA b,5,0,24,b,5,0,41,b,5,0,25,b,6,0,39,b,6,0,26,b,6,0,37,b,6,0,28,b,6,0,35,b,6,0,30,b,6,0,33,b
DATA 6,0,32,b,7,0,29,b,7,0,34,b,8,0,25,b,8,0,36,b,9,0,21,b,9,0,38,b,10,0,17,b,10,0,41,b,12,0,9,b,12
DATA 0,44,b,33,0,47,b,29,0,51,b,25,0,57,b,18,0,64,b,9,100000,0
Re: 3D Gaming Project
Post by Ric on Sep 4th, 2016, 3:45pm
Michael
Seems to work pretty nice. I have altered the code a bit to speed it up and make it loop until you press spacebar.
If you were to change the code to make the pixels a colour on a bitmap instead of DRAWing them this would speed thing up massively, (DRAW is very slow) and you would have the beginnings of a sprite printing routine.
Code: VDU 22,8
VDU 23,23,1|
OFF:VDU 5:COLOUR 0:CLG
REPEAT REM ****** HERE ******
PROC_image(RND(1000),RND(1000))
RESTORE
UNTIL INKEY(-99)=-1
WAIT 0:END
DEF PROC_image(h,v)
u=0:r=0:g=0:b=0:a=0:c=0:t=0
ost$=""
READ x,y:REPEAT
READ nst$,t
IF nst$="0" THEN r=0:g=0:b=0 :REM 'black 0 0 0
IF nst$="1" THEN r=192:g=128:b=64:REM ' brown 192 128 64
IF nst$="2" THEN r=64:g=64:b=192 :REM'dark blue 64 64 192
IF nst$="3" THEN r=128:g=128:b=128:REM' dark grey 128 128 128
IF nst$="4" THEN r=128:g=0:b=0:REM'dark red 128 0 0
IF nst$="5" THEN r=224:g=192:b=0 :REM'dark yellow 224 192 0
IF nst$="6" THEN r=128:g=160:b=192:REM'flat blue 128 160 192
IF nst$="7" THEN r=32:g=192:b=64 :REM'green 32 192 64
IF nst$="8" THEN r=166:g=202:b=240:REM'light blue 166 202 240
IF nst$="9" THEN r=192:g=192:b=192:REM 'light gray 192 192 192
IF nst$="a" THEN r=192:g=224:b=0:REM 'light green 192 224 0
IF nst$="b" THEN r=224:g=32:b=64:REM'light red 224 32 64
IF nst$="c" THEN r=0:g=160:b=192 :REM'medblue 0 160 192
IF nst$="d" THEN r=224:g=128:b=64 :REM 'orange 224 128 64
IF nst$="e" THEN r=224:g=160:b=192:REM'pink 224 160 192
IF nst$="f" THEN r=160:g=64:b=192:REM'purple 160 64 192
IF nst$="g" THEN r=192:g=220:b=192:REM'tan 192 220 192
IF nst$="h" THEN r=255:g=255:b=255:REM'white 255 255 255
IF nst$="i" THEN r=255:g=255:b=0:REM'yellow 255 255 0
COLOUR 0,r,g,b:GCOL 0
FOR u=0 TO t
a=a+1: MOVE h+c,v-a
IF nst$<>"0" THEN DRAW h+c,v-a : REM ****** HERE ******
IF a>x THEN c=c+1:a=0
NEXT u
UNTIL nst$="100000"
MOVE 0,0:ENDPROC
DATA 79,79
DATA 0,595,b,9,0,65,b,17,0,57,b,25,0,51,b,29,0,48,b,31,0,45,b,12,0,9,b,12,0,42,b,10,0,16,b,10,0,38,b,9,0
DATA 21,b,9,0,36,b,8,0,25,b,8,0,34,b,7,0,29,b,7,0,32,b,7,0,32,b,6,0,30,b,6,0,35,b,6,0,28,b,6,0,37
DATA b,6,0,27,b,5,0,39,b,6,0,25,b,5,0,41,b,5,0,24,b,5,0,28,i,3,0,10,b,5,0,23,b,5,0,28,i,4,0,10,b
DATA 5,0,21,b,5,0,29,i,4,0,10,b,5,0,20,b,5,0,30,i,5,0,10,b,5,0,19,b,5,0,12,i,2,0,15,i,5,0,9,b,5
DATA 0,18,b,5,0,11,i,6,0,14,i,4,0,10,b,5,0,17,b,5,0,11,i,7,0,13,i,5,0,9,b,5,0,17,b,4,0,12,i,7,0
DATA 14,i,4,0,10,b,4,0,17,b,4,0,12,i,7,0,15,i,4,0,9,b,4,0,16,b,5,0,12,i,5,0,17,i,4,0,10,b,4,0,15
DATA b,4,0,37,i,4,0,10,b,4,0,15,b,4,0,37,i,4,0,10,b,4,0,15,b,4,0,38,i,4,0,9,b,4,0,14,b,4,0,39,i
DATA 4,0,10,b,4,0,13,b,4,0,39,i,4,0,10,b,4,0,13,b,4,0,39,i,4,0,10,b,4,0,13,b,4,0,39,i,4,0,10,b,4
DATA 0,13,b,4,0,39,i,4,0,10,b,4,0,13,b,4,0,39,i,5,0,9,b,4,0,13,b,4,0,39,i,5,0,9,b,4,0,13,b,4,0
DATA 39,i,5,0,9,b,4,0,13,b,4,0,39,i,4,0,10,b,4,0,13,b,4,0,39,i,4,0,10,b,4,0,14,b,4,0,38,i,4,0,9
DATA b,4,0,15,b,4,0,16,i,2,0,17,i,5,0,9,b,4,0,15,b,4,0,15,i,4,0,16,i,4,0,10,b,4,0,15,b,4,0,14,i
DATA 6,0,15,i,4,0,10,b,4,0,16,b,4,0,12,i,7,0,14,i,5,0,9,b,5,0,16,b,4,0,12,i,7,0,14,i,4,0,10,b,4
DATA 0,17,b,5,0,12,i,5,0,15,i,3,0,10,b,5,0,17,b,5,0,33,i,4,0,10,b,5,0,18,b,5,0,31,i,5,0,9,b,5,0
DATA 19,b,5,0,30,i,4,0,11,b,5,0,20,b,5,0,29,i,3,0,11,b,5,0,22,b,4,0,29,i,2,0,12,b,5,0,22,b,5,0,43
DATA b,5,0,24,b,5,0,41,b,5,0,25,b,6,0,39,b,6,0,26,b,6,0,37,b,6,0,28,b,6,0,35,b,6,0,30,b,6,0,33,b
DATA 6,0,32,b,7,0,29,b,7,0,34,b,8,0,25,b,8,0,36,b,9,0,21,b,9,0,38,b,10,0,17,b,10,0,41,b,12,0,9,b,12
DATA 0,44,b,33,0,47,b,29,0,51,b,25,0,57,b,18,0,64,b,9,100000,0
Ric.
ps If you select an object ADD OBJECT>>QUICK>>*any shape (except triangleoid)* Then make the object the centre of focus by right clicking the pink node at its centre, you should get a red node and green axis lines, then the four inner sliders should resize and rotate the object and not the whole picture, also you should be able to change the colour as well.
Happy programming
Re: 3D Gaming Project
Post by DDRM on Sep 5th, 2016, 12:26pm
Hi Ric,
That's very nice - well done! That's exactly the kind of thing I had in mind for your second sliders.
Would it be useful to be able to type the xyz coordinates of an object, as well as position it manually?
D
Re: 3D Gaming Project
Post by michael on Sep 5th, 2016, 4:18pm
Quote:If you were to change the code to make the pixels a colour on a bitmap instead of DRAWing them this would speed thing up massively |
|
Are you referring to sprites or RECTANGLE TO?
Or are you referring to another idea?
Re: 3D Gaming Project
Post by Ric on Sep 5th, 2016, 9:57pm
To DDRM
Yes, but not yet. It will be possible via the existing coordinate display just like a normal windows view/menu, also for the colour sliders, just not got round to it yet. 
To Michael
I will send you a piece of code that DDRM sent me a while back to create a DIBsection and thus use pixel colouring instead of DRAWing.
Ric
Re: 3D Gaming Project
Post by Ric on Sep 7th, 2016, 9:17pm
Evening all,
This will be the last update for a while, I have implemented node manipulation so if you choose solid+nodes or line+nodes when an object has been made the main focus you will be able to move individual nodes and create odd shapes.
This in its self has high lighted a problem that has existed since the beginning. When I first created the asm routines to print the graphics I used rhomboids not triangles as it was easier to implement picture transfer to the object, this will now have to be addressed because the lighting routines only work if all the nodes in a particular rhomboid are on the same plane, which potentially they now may not be! Have a play and you will see that the lighting goes cock-a-hoot if you move a node on the sphere for example.
https://my.pcloud.com/publink/show?code=XZJQEWZlFYfzeoLRsBYMlS1riPYDXr5T2vX
Once I have sorted triangles I will get back to the design IDE.
Ric.
Thanks for the interest.
Re: 3D Gaming Project
Post by michael on Sep 13th, 2016, 3:13pm
Hey Ric, you mentioned you were going to send me something for making a replacement for draws?
Re: 3D Gaming Project
Post by Ric on Sep 18th, 2016, 10:50am
Sorry its taken so long Michael,
Here is the code as promised, I have annotated it and put in a few examples, so hopefully it will do the job.
Code:
REM The 3rd and 4th components of the VDU 23,22 statement must be the same as bmi.Header.Width% and bmi.Header.Height%
VDU 23,22,1024;640;16,16,16,0
DIM BITMAPINFOHEADER{Size%, Width%, Height%, Planes{l&,h&}, BitCount{l&,h&}, Compression%, SizeImage%, XPelsPerMeter%, YPelsPerMeter%, ClrUsed%, ClrImportant%}
DIM bmi{Header{} = BITMAPINFOHEADER{}}
bmi.Header.Size% = DIM(BITMAPINFOHEADER{})
bmi.Header.Width% = 1024
bmi.Header.Height% = 640
bmi.Header.Planes.l& = 1
bmi.Header.BitCount.l& = 32
SYS "CreateDIBSection", @memhdc%, bmi{}, 0, ^bits%, 0, 0 TO hbitmap%
IF hbitmap%=0 ERROR 100, "Couldn't create DIBSection"
SYS "SelectObject", @memhdc%, hbitmap% TO oldhbm%
SYS "DeleteObject", oldhbm%
SYS "InvalidateRect", @hwnd%, 0, 0
REM The code to this point sets the screen size in pixels and creates bitmap to the same size
REM To access the bitmap you need to use bit% :-
REM Each pixel is four bytes
REM You can access one at a time with "bits%?(X,Y)=8_bit_number"
REM Or all four bytes at the same time "bits%!(X,Y)=&aaRRGGBB
REM when setting X and Y remember they are pixel coordinates not graphics coordinates
X=100
Y=100
bits%?( ( X + ( Y * bmi.Header.Width% ) ) * 4 ) = 255 : REM Will put a blue dot at 100,100
X=110
bits%!( ( X + ( Y * bmi.Header.Width% ) ) * 4 ) = &00FF00FF : REM Will put a magenta dot at 110,100
REM The reason for the "* bmi.Header.Width%" is to move the "Y" position up the screen by the correct displacement
REM and the "*4" is because each position on the bit map is four pixels
REM A simple line
FOR loop = 200 TO 400
bits%!( ( loop + ( loop * bmi.Header.Width% ) ) * 4 ) = &00FF8000
NEXT
REM After you have finished accessing the bit map a "*REFRESH" is needed to update the screen
*REFRESH
Regards Ric
Re: 3D Gaming Project
Post by michael on Sep 18th, 2016, 1:20pm
Perfect! I think I have an idea of how it works.
And you posted it just in time. I am working on toon body parts that actually have function. ( I have free time to work on projects.)
Once I get a proper sample done, I think it will help some people with toon animations and game piece creation tools.
Why build each piece from the ground up, when you can just place the piece or many and it can be instructed to follow commands?
It will probably take me all day to get the first piece designed.
Is it alright for me to share my animation tools with this code on Richards forum and on the group board?
Re: 3D Gaming Project
Post by Ric on Sep 18th, 2016, 3:07pm
Of course, the code is originally Richards I think.
Re: 3D Gaming Project
Post by Ric on Sep 27th, 2016, 9:27pm
Just thought I would share this, I have now sorted the triangle algorithm and this is the result. As a bonus I have added shading in the gouraud style.
https://my.pcloud.com/publink/show?code=XZdC11ZBvfqxwcn38SIcp6EySb0tROX5wJ7
Keep the number of sides down below 15 and use
node 0 shade 100
node 1 shade 0
node 2 shade 200
to demonstrate the effects.
Ric
Re: 3D Gaming Project
Post by David Williams on Sep 27th, 2016, 9:38pm
The image 'Paisley' is missing, resulting in a "Invalid channel" error.
David.
--
Re: 3D Gaming Project
Post by Ric on Sep 28th, 2016, 07:27am
Thanks David,
I was very tired and off to bed last night when I posted. The two links should have been :-
https://my.pcloud.com/publink/show?code=XZ0qM1ZskpbmqsNIX8PCoortuysWbxY9uyy
https://my.pcloud.com/publink/show?code=XZdC11ZBvfqxwcn38SIcp6EySb0tROX5wJ7
Ric
Re: 3D Gaming Project
Post by Ric on Oct 1st, 2016, 1:25pm
Afternoon chaps, I have completed the first phase of turning the paisley triangle into a 3D image. Try this :-
https://my.pcloud.com/publink/show?code=XZ2w7eZ9CNlqYttwWSlJ7hxuJ5ztFNtDSYy
Its very slow and the algorithm for clipping backward facing side does not exist but it does demonstrate how well it is going to work. ( You still need the file "paisley" in the same folder as this file. )
Ric
Re: 3D Gaming Project
Post by Ric on Oct 14th, 2016, 12:21pm
It has taken a long time to convert to ASM but here goes
(Only the raster coding is in ASM, the vector calcs are still in BASIC, this will come later)
https://my.pcloud.com/publink/show?code=XZENvnZLIQK2Mf2wUpGfhnjVz7wHutkgy87
https://my.pcloud.com/publink/show?code=XZ0qM1ZskpbmqsNIX8PCoortuysWbxY9uyy
There are two lines of code with ******* in them, if you remove the ; from the beginning then sphere will turn green so you can see the success/fail of the highlighted spot!!!!! This is due to the gouraud shading algorithm so I am now working on phong shading to address this.
Re: 3D Gaming Project
Post by michael on Oct 19th, 2016, 1:05pm
Impressive work. The sphere and texture is functional. I don't know what paisley is for. It just shows a white window. Perhaps I need to wait longer?
As for the sphere, is there a way to drive in the world yet?
Re: 3D Gaming Project
Post by Ric on Oct 19th, 2016, 4:36pm
The texture on the sphere should be of Paisley pattern. Also a block pattern of Paisley should appear on the right side of the screen with the out line of the triangle to be transposed on it. There is no way of interacting yet, I am trying to get all the graphics working before I make that leap.
Re: 3D Gaming Project
Post by Ric on Nov 4th, 2016, 10:14pm
This is the latest attempt. I am sure you will agree that it is a vast improvement on the last routines. It has a shading engine for smooth skinning and is 60 to 65% faster than before. I will implement them into the design package soon, but for now I would be grateful if someone could run them on a machine better than mine and give me feed back on the fps at 16 faces and diameter of 200 and 30 faces at 300 diameter.
https://my.pcloud.com/publink/show?code=XZ8snTZq9Cw6m1zfp8pUIk2bDHxL74zthOX
and you will need
https://my.pcloud.com/publink/show?code=XZmsnTZId8TOsQmzbS510PXlEMtdHBFAtXX
The effect should be a green ball with purple dots.
Happy viewing
Ric
As an aside does anyone know anything about multicore functions?
Re: 3D Gaming Project
Post by David Williams on Nov 5th, 2016, 09:11am
Nice bit of code, Ric!
You weren't a demo coder in the past, were you? I may have asked you this before.
On my system (Intel Core i7-4790 @ 3.60 GHz, Windows 10 64-bit):
16 faces, radius 200: 248 fps
30 faces, radius 300: 143 fps
(although, of course, the frame rates vary a bit from one run to the next)
David.
--
Re: 3D Gaming Project
Post by Ric on Nov 5th, 2016, 12:26pm
Thanks very much for the compliment and information David, but no I was not a demo coder. Very early on in my coding history ( I was about 11 and 6502 ) I discovered that if you do not annotate ASM to death it is impossible to read even simple code that you have written yourself, never mind anyone else.
The information about speed you have supplied would suggest that a full screen 3D scroll might be achievable at about 30 fps on a modern machine, which is not too shabby, but some where closer to 60 fps would produce a better result. The answer to the question about multi-coring hopefully might give a route to this goal.
Do you know if it is possible to run two independent (ie running in parallel not sequentially) ASM routines from the same BB4W program?
I know multi-threading is possible, but I would like to have a routine running in the background (another core) that can be triggered from another routine by changing a memory location to switch it on.
Here's hoping
Ric
Re: 3D Gaming Project
Post by Ric on Apr 5th, 2017, 7:48pm
Evening folks,
Sorry ive been away for a while with no updates, but this is because there were no updates to give. It has taken a long time to get to this stage as you can tell by the file name (some of the attempts had 30 subsections),
it turns out that one can get bogged down with fancy mathematics trying to interpolate 1/z or using triangular numbers to correct the perspective, but the solution I have come up with is much simpler, both mathematically and more importantly, in the coding. I have simply interpolated the perspective corrected z, spritex and spritey values and the inverse perspective corrected them to produce the correct appearance. SIMPLE!!!!!!!!Not.
Unfortunately the speed has taken a hit, although more than I hoped, not as much as I had feared losing about 22%.
"z" and "x" rotate around the x axis
"y" and "u" rotate around the y axis
"m" and "n" rotate around the z axis
https://1drv.ms/u/s!AqibHqCkE1VQkF-dXatZ8cCHNSaO
Let me know if the download works?
Re: 3D Gaming Project
Post by DDRM on Apr 6th, 2017, 08:08am
Hi Ric,
Glad to hear that you are still making progress!
The download seemed fine, but when I run it I just get a wide (too wide for my monitor!) black window with nothing in it to rotate, and no obvious menus or any controls to make/load a shape?
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on Apr 6th, 2017, 10:13am
Thanks DDRM.
I don't know why this is, can you access the code? The window that opens should be the same as it always was 1346,674 pixels. There is only a grid to rotate which is done with the keys above. Can you let me know further so if necessary I can change the delivery method.
Regards Ric
Re: 3D Gaming Project
Post by Ric on Apr 8th, 2017, 09:46am
I have changed the size of the window that opens so it should be suitable for all screen sizes, the demo isn't that interesting I know, it is just to demonstrate perspective correct rastering. When the demo loads you should get a blank window with the grid perpendicular to the screen giving the impression it is not there, play with the keys above and it will appear.
https://1drv.ms/u/s!AqibHqCkE1VQkGByTy3QTb7XS5ai
Regards Ric
Re: 3D Gaming Project
Post by DDRM on Apr 8th, 2017, 2:35pm
It works!
It probably worked before, but I couldn't see anything: it never occurred to me that that was because it was edge-on...

D
Re: 3D Gaming Project
Post by Ric on Apr 9th, 2017, 08:01am
Thanks D
Next phase is to turn rotations to arbitory axis instead of screen axis, and then implement mouse controls but no like last time.
Ric
Re: 3D Gaming Project
Post by Ric on Apr 19th, 2017, 9:23pm
Evening guys
I have been working on making the grid controlable by mouse. Not that difficult in itself, but harder to make it intuitive. Here is what I have come up with.
Try clicking and holding the left button and moving the mouse and then try clicking and holding the right button and then move the mouse.
https://1drv.ms/u/s!AqibHqCkE1VQkGboDYD849xXcOL-
Can you let me know how it feels.
Regards Ric
Re: 3D Gaming Project
Post by DDRM on Apr 20th, 2017, 08:17am
Hi Ric,
That seems to work nicely: the behaviour with the left button seems pretty intuitive. I'm not quite sure what the right button is doing: moving the mouse sideways moves the grid, but moving the mouse forwards and backwards moves the pointer but not the grid, thus allowing you to reposition the pointer? It seems over-sensitive? What is the number displayed?
best wishes,
D
Re: 3D Gaming Project
Post by Ric on Apr 20th, 2017, 08:42am
Thanks D
When the right mouse button is pressed the grid should rotate about the screen z axis. I will adjust the sensitivity and repost.
The number is the angle of the mouse to the z axis in relation to the centre of the screen.(in radians) it's only there so I could check stuff was working.
Regards Ric
Re: 3D Gaming Project
Post by Ric on Apr 28th, 2017, 8:13pm
Hello
In reply to DDRM I have adjusted the sensitivity of the mouse input and I have introduced a pool ball image to help with fathoming the rotations.
Have a go and let me know
The image is about 25fps
https://1drv.ms/u/s!AqibHqCkE1VQkHRi24qaQHvtiziR
https://1drv.ms/u/s!AqibHqCkE1VQkHWaYrfbgUkur7Pq
Regards Ric
Re: 3D Gaming Project
Post by DDRM on Apr 29th, 2017, 08:25am
Hi Ric,
It works nicely: fast and smooth. I chose 24 "vertical sides" or whatever it asked for, which seemed to be a good compromise. I could see a little tear-out at the top of the ball, but it wasn't offensive. I tried a lot more (128), and it became a lot worse - I guess it's an edge effect (are the adjacent sections overwriting each other, or something?). 12 looked pretty good, but the ball was distinctly not round!
Understanding what the right mouse button does means it makes a lot more sense - rotates around the axis running straight out of the screen.
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on May 9th, 2017, 8:39pm
WELL!!
Sometimes when you make 1 step forward you make two backwards. I have made bounds in creating threads, but have discovered that unless you have the cpu count to allow you to take advantage it is meaningless of even worse, SLOWER.
Have a go at these four versions of the same code and let me know the results for 24 faces in fps. I think you will be surprised.
0 threads
https://1drv.ms/u/s!AqibHqCkE1VQkH0rpz1h9YdJMqeA
1 thread
https://1drv.ms/u/s!AqibHqCkE1VQkH-5djlSI_N6xcXu
2 threads
https://1drv.ms/u/s!AqibHqCkE1VQkQCH9_YmXdpd0Q1A
4 threads
https://1drv.ms/u/s!AqibHqCkE1VQkH5nCRLFHvUOC-_H
the sprite image
https://1drv.ms/u/s!AqibHqCkE1VQkHWaYrfbgUkur7Pq
Good luck
Ric
Re: 3D Gaming Project
Post by DDRM on May 10th, 2017, 08:24am
Hi Ric,
I found 1 or 2 threads about the same speed, and about 30% faster than "no threads". The four threads version slowed to a crawl - about 10% of the speed of the 1 thread version. This is a quad-core machine, so with nothing else happening (very unlikely on a networked machine with my email running!), in principle using up to 4 threads (total) might give a speed gain.
Obviously you can't actually have "no threads", or the processor wouldn't process, so is your thread number "additional threads"?
It's actually not surprising that things slow down with too many ("parallel") threads, though perhaps it's surprising that the slow down is so severe.
If the number of threads exceeds the number of processors/cores available, at least one processor will end up having to run more than one thread. There will probably be a significant overhead as it switches between, them, too.
It depends a bit on how you arrange your "parallel" processing. If you have to keep things in synchrony (for example if each thread renders 1/n of each frame), then any delay on one thread will result in all the others sitting doing nothing for a substantial time.
In a perfect world, having n+1 threads might result in core 1 having to run two threads, thus taking twice as long to get the data for a single frame. Of course, if it is switching multiple times between the two threads, to give them each a "fair crack of the whip", the overheads will go up substantially.
In a less perfect world, the operating system might keep core 1 for monitoring my email, core 2 for doing all the multitudinous other things happening in the background, give thread 1 to core 3, and then share core 4 amongst the other 3-4 threads, switching between them every ms or so. That would have a catastrophic effect on performance.
In contrast to CPUs, which typically have 1-4 cores, I understand that graphics processors are often designed to use multiple parallel processes. Do you have a graphics card? Is there any way of getting your threads to run on those? You'd need to talk to Richard about that, I suspect... or consider using DirectX, which presumably does exactly that...
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on May 10th, 2017, 6:59pm
Yep, your right, that's the conclusion I came to too. I am looking in to Direct X as x86 doesn't run on the graphics cards. Now I understand how to produce the graphics routines Direct X I think is going to be a good solution combined with x86 asm to do all the calculations.
Ric
Re: 3D Gaming Project
Post by Ric on Jul 7th, 2017, 1:52pm
Afternoon guys,
I have finally cracked the slight breaking out of the pixels and here are the results.
Although this is all still a step backwards from the design package I had to sort it all before carrying on.
Have a play with the parameters and let me have some feedback.
Just for a gag I have made the light source orbit the object.
https://1drv.ms/f/s!AqibHqCkE1VQkSXPQeI-oWX3eMU4
Regards Ric
Re: 3D Gaming Project
Post by michael on Jul 8th, 2017, 2:23pm
Excellent work on the spinning earth with lighting
Re: 3D Gaming Project
Post by Ric on Jul 8th, 2017, 5:56pm
Thanks Michael, have you tried playing with the parameters? Note the fps when you choose flat side colour cube.
Re: 3D Gaming Project
Post by michael on Jul 9th, 2017, 02:38am
Quote: have you tried playing with the parameters |
|
Yes I have.
One suggestion. I am thinking you are able to handle multiple objects on the same screen. Perhaps a turn based application like a 3D board game could be made with predefined shapes that can have textures.
The speeds I am seeing are plenty fast for most gaming applications or 3D design apps.
I would think focusing on making a shape library for the 3D world and making it easy to locate using perhaps a command like:
PROCsphere(x,y,z,rotx,roty,scale,spherenumber)
x- right/left coordinates
y-distance coordinate
z-up down coordinate
rotx - facing side rotate clockwise
roty- facing side roll
scale - size of sphere at closest range
spherenumber- would allow many spheres of different sizes and positions to exist
Just some ideas
Re: 3D Gaming Project
Post by Ric on Jul 9th, 2017, 07:02am
You are right, but a little ahead of my plans.
. My next step is to finish the object designer I was working on before I had the triangle dilemma. This will enable you to create your own object library and then call them with a PROC or something similar.
Cheers
Re: 3D Gaming Project
Post by David Williams on Nov 9th, 2017, 07:06am
Any updates on this project, Ric?
Re: 3D Gaming Project
Post by Ric on Nov 11th, 2017, 10:21pm
Yes is the short answer. I have had to take a very quick crash course in quarternians, not an easy subject to find laymans terms on. However this has now been solved and a new IDE has been introduced to boot. The problem I have is that the tool bar in the new window requires many images to be present to load up and I do not know how to pass these images on, other than to give links to them all, is there an easier way? If this can be solved I will post the latest update which includes a few rotation tricks and arbitory axis rotation.
Ric
Re: 3D Gaming Project
Post by David Williams on Nov 12th, 2017, 02:45am
on Nov 11th, 2017, 10:21pm, Ric wrote:The problem I have is that the tool bar in the new window requires many images to be present to load up and I do not know how to pass these images on, other than to give links to them all, is there an easier way? |
|
I don't think I can help, but maybe someone else here can? I think Richard is the best person to ask (on the other forums), and doing so usually gets results!
David.
--
Re: 3D Gaming Project
Post by DDRM on Nov 14th, 2017, 08:07am
Hi Ric,
Not sure I understand the question: do you mean how do you make the images available to us, so we can see your progress? Can you package them as a single zip archive?
If you compiled your program to an exe, it would have all the resources packaged with it? That has the downside that we can't see the code, but I'm not sure how many of us are going to dissect it that carefully, especially if it means learning about quaternions first! If you want comments on it, you could provide the source code separately.
On the topic of quaternions, fancy providing us with an idiot's guide? Ideally you could post it on the the BBC Basic Wiki...
If your question is whether there is a better way to get them into your program than a long list of load commands, I don't know of one, which isn't the same as saying there isn't one... One option might be to combine them in one big image, and then blit the relevant bit into individual images in memory, but I can't see that that's any easier - indeed, probably harder!
Best wishes,
D
Re: 3D Gaming Project
Post by Ric on Nov 17th, 2017, 9:30pm
Think the answer is to create a link to a folder. Too late to try now, but will give it a whirl tomorrow.
Re: 3D Gaming Project
Post by Ric on Nov 18th, 2017, 3:06pm
I have been working on a more friendly IDE for my 3D object design, not all of it works yet so please be patient when trying it out.
Delete Object - Works
Create Quick Object - Works
Grid - Works
Rotate Grid to XY Plane - Works
Rotate Type - Works (but not on faces)
Rotate Style - Works
Quick Scale - Works
To highlight an object a short click with the left hand mouse button
To rotate the grid in any other mode except grid mode hold shift and rotate as normal
THE REST SHOULD BE INTUATIVE
Let me Know.
https://1drv.ms/f/s!AqibHqCkE1VQllkSrc7Jifpn2wZS
Just realised that I have used counting loops to calculate a short or long press of the mouse buttons, if you get no joy with anything I will post a version using TIME to do the calculations later.
Re: 3D Gaming Project
Post by Ric on Nov 18th, 2017, 3:11pm
The answer to posting an idiots guide to quarternions is, I will post a guide on here when I get a chance and someone else can put it on wiki (I don't know how to do it).
They are not to be afraid of, once you realise you don't need to know the maths, just the result, with a few tweaks, they become very easy to use.
Ric
Re: 3D Gaming Project
Post by Ric on Nov 18th, 2017, 4:23pm
A bit earlier than I thought, here is the version with the use of TIME.
Ric
https://1drv.ms/f/s!AqibHqCkE1VQllkSrc7Jifpn2wZS
Re: 3D Gaming Project
Post by Ric on Dec 3rd, 2017, 9:02pm
Evening all,
I have just added grouping of objects, it adds an important part of the final puzzle and takes me one huge step closer to a usable IDE for creating 3D game objects.
Could someone let me know how you get on and if it is user friendly enough.
https://1drv.ms/f/s!AqibHqCkE1VQln2sROL6ah0gHbIX
Regards Ric