BBC BASIC
« Quest for fire library (group effort ) »

Welcome Guest. Please Login or Register.
Jan 20th, 2018, 4:18pm


Cross-platform BBC BASIC (Win32, Linux x86, Android, Mac OS-X, Raspberry Pi)

« Previous Topic | Next Topic »
Pages: 1 2  Notify Send Topic Print
 hotthread  Author  Topic: Quest for fire library (group effort )  (Read 394 times)
DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 29
xx Re: Quest for fire library (group effort )
« Reply #15 on: Jan 11th, 2018, 3:13pm »

Hi Richard,

Actually the flames themselves are rendered flat at the moment, though their positioning relative to each other and the logs uses the Z dimension, and the logs are cylinders, arranged in 3D. Yes, I really meant OpenGL for the 3D work in BBC-SDL.

The main reason I went for D3D was the Gouraud shading. The transparency is also nice, though as I say it doesn't seem to be working very well - in my flight sim you could see through the propeller disc very nicely, but the transparency is much higher- that makes the flames nigh on invisible, but still doesn't work. I like the idea of GDIP - I'll have a think.

I don't think not having the emissivity is a deal-breaker.. smiley

Best wishes,

D
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Quest for fire library (group effort )
« Reply #16 on: Jan 12th, 2018, 09:48am »

on Jan 11th, 2018, 09:04am, DDRM wrote:
Here's the code for the logs: you'll need my Make3DLib

This code fails with an 'Invalid channel' error for me. After a little investigation the cause appears to be this line in your Make3DLib library:

Code:
      f%=OPENOUT(@dir$+name$+".FVF") 

@dir$ is, of course, commonly a 'read only' directory. It's where the program itself is stored, which will typically be in a 'protected' folder - and it certainly is when one simply copies-and-pastes code from a web site into a freshly-opened BB4W IDE as I did.

Therefore you should not attempt to open a file for writing in @dir$, and certainly not in a library! Places that are 'guaranteed' to be writable include @tmp$ (for temporary files that are not wanted after the program ends) and @usr$ (for files which need to be kept from one 'session' to the next, such as a high-score table).

I put 'guaranteed' in quotes because OPENOUT may still fail in those directories if the file is locked (e.g. currently open by another program) or read-only. This can largely be avoided by using a 'unique' filename such as one containing a UUID or a random number or the date/time etc.

Richard.
User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 29
xx Re: Quest for fire library (group effort )
« Reply #17 on: Jan 12th, 2018, 10:14am »

OK, I've sorted out a couple of things. It turns out the order you render the buffers is critical: if you want things to show through, they need to have been rendered first - at least, when I put the logs in buffer 0 they show through, rather than being hidden. If you change Z(0)=0.8 to Z(0)=0.5, you'll be able to see the flames interleaved with the logs, since the front log is now closer than the flames.

I've also amended the code so that the flames become more transparent (less opaque) as they get higher. I don't know if you like it, but it demonstrates a technique...

I spotted that a problem I'd had earlier was not due to memory within BB4W, but the way I reserved buffer space, so I've removed the HIMEM change at the beginning.

Best wishes,

D
Code:
MODE 21

nbufs%=4
REM Here I'm actually reserving arrays 1 BIGGER than nbufs% (i.e. 0 - nbufs%), which gives me one for background scene - here, the logs
DIM l%(0), b%(nbufs%), n%(nbufs%), f%(nbufs%), s%(nbufs%), m%(nbufs%), t%(nbufs%), y(nbufs%), p(nbufs%), r(nbufs%), X(nbufs%), Y(nbufs%), Z(nbufs%), e(2), a(2)

INSTALL @lib$+"D3DLIBA"

ON CLOSE PROCcleanup(nbufs%):QUIT
ON ERROR PROCcleanup(nbufs%):PRINT REPORT$:END

d% = FN_initd3d(@hwnd%, 1, 1)
IF d% = 0 ERROR 100, "Can't initialise Direct3D"

REM Set alpha blending
SYS !(!d%+200),d%,27,1:REM SetRenderState(Alphablendenable)
SYS !(!d%+200),d%,19,5:REM SetRenderState( set source blend to D3DBLEND_SRCALPHA)
SYS !(!d%+200),d%,20,6:REM SetRenderState(set destination blend to D3DBLEND_INVSRCALPHA)
SYS !(!d%+200),d%,148,1:REM SetRenderState(set emissive materialcoloursource to "diffuse vertex colour")

DIM l%(0) 103
l%(0)!0 = 3 : REM directional light, taken from manual (parameters adjusted)
l%(0)!4 = FN_f4(1)  : REM red component
l%(0)!8 = FN_f4(1)  : REM green component
l%(0)!12 = FN_f4(1) : REM blue component
l%(0)!64 = FN_f4(0.5) : REM. X component of direction
l%(0)!68 = FN_f4(-0.50) : REM. Y component of direction
l%(0)!72 = FN_f4(0.2) : REM. Z component of direction

nv%=26*12 :REM number of layers * 4 triangles (2 on each side between this layer and the next). Amend if you change the n% in PROCWriteVBufData!

REM Set up vertex buffer by loading the background "scene" - here it's just 3 logs!
b%(0)=FN_load3d(d%,"logs.fvf",n%(0),f%(0),s%(0))
IF b%(0)=0 THEN PROCcleanup(nbufs%):PRINT "Logs failed to load!":END
X(0)=-0.2
Y(0)=0.3
Z(0)=0.8

REM Set up vertex buffers for each flame
FOR x%=1 TO nbufs%
  n%(x%)=nv%
  f%(x%)=&52
  s%(x%)=28
  X(x%)=(x%-0.8)/2
  Y(x%)=(x% MOD 2)*0.5
  b%(x%)=FN_setupVbuf(d%,n%(x%),f%(x%),s%(x%))
  IF b%(x%)=0 THEN PROCcleanup(nbufs%):PRINT x%,"Disaster!":END
NEXT x%

e() = 0,0,-10  :REM Eye/camera position
a() = 0, 1, 0  :REM Point you are looking at (centre of screen)


FOR duration%=0 TO 100
  FOR x%=1 TO nbufs%
    PROCWriteVBufData(b%(x%),n%(x%),s%(x%),1,2)   :REM Re-write the actual vertex data to make flames flicker
  NEXT x%
  PROC_render(d%, &FF101010, 1, l%(), nbufs%+1, m%(), t%(), b%(), n%(), f%(), s%(), y(), p(), r(), X(), Y(), Z(), e(), a(), PI/4, 5/4, 1, 1000,0)
  WAIT 10
NEXT duration%
PROCcleanup(nbufs%)
END
:
DEF FN_setupVbuf(D%,N%,V%,L%)  :REM Adapted from D3DLib (as some of the other D3D stuff!)
LOCAL B%,R%
SYS!(!D%+92),D%,N%*L%,0,V%,0,^B% TO R%:REM CreateVertexBuffer
IF R% THEN=0
=B%
:
DEFPROCWriteVBufData(B%,N%,L%,w,h)
LOCAL P%,vb%
LOCAL x%,n%,n2%,c1%,c2%,dc%,hn,hw,dw,f()
n%=5  :REM you can change this to change the shape/detail of the flame - there will be n%^2 layers.
REM If you make n% more than 5, you will need to increase the space allocated for the buffers, or it will crash!
REM Now  calculate coordinates for flame
n2%=n%^2
hn=n%/2
DIM f(n2%+1,2)
hw=w/2
dw=hw*0.8
FOR x%=0 TO n2%
  f(x%,1)=RND(x%)/(4*n2%)
  f(x%,0)=f(x%,1)-hw+ABS(dw-dw*SQR(x%)/hn)+RND(x%)*hw/(8*n2%)
  f(x%,2)=f(x%,1)+hw-ABS(dw-dw*SQR(x%)/hn)-RND(x%)*hw/(8*n2%)
NEXT x%
f(n2%+1,1)=RND(n2%)/(2*n2%)
f(n2%+1,0)=f(n2%+1,1)
f(n2%+1,2)=f(n2%+1,1)
REM Now write it into the buffer
SYS!(!B%+44),B%,0,N%*L%,^P%,0:REM pVB::Lock
vb%=P%  :REM vb% is a pointer to where we have got to in the buffer
dc%=(1<<16)-(2<<8)-1 :REM calculate difference in colour for one level higher
FOR x%=0 TO n2%
  REM Calculate colours for edge and centre of the flame at this level
  c1%=((160+x%)<<16)+((130-2*x%)<8)+26-x% +((&80-x%*5)<<24)  :REM Last section controls opacity
  c2%=((190+x%)<<16)+((158-x%)<<8)+55-x%  +((&80-x%*5)<<24)  :REM Change the "x%*5" to reduce the fade-out of flames
  REM write data for the trapezium between this level and the next
  REM 4 triangles, two from the left edge to the centre, and two from the right edge to the centre
  PROCDoPoint(f(x%,0),x%*h/(n2%+1),0,c1%,vb%)
  PROCDoPoint(f(x%+1,1),(x%+1)*h/(n2%+1),0,c2%-dc%,vb%)
  PROCDoPoint(f(x%,1),x%*h/(n2%+1),0,c2%,vb%)
  
  PROCDoPoint(f(x%,0),x%*h/(n2%+1),0,c1%,vb%)
  PROCDoPoint(f(x%+1,0),(x%+1)*h/(n2%+1),0,c1%-dc%,vb%)
  PROCDoPoint(f(x%+1,1),(x%+1)*h/(n2%+1),0,c2%,vb%)
  
  PROCDoPoint(f(x%,2),x%*h/(n2%+1),0,c1%,vb%)
  PROCDoPoint(f(x%,1),x%*h/(n2%+1),0,c2%,vb%)
  PROCDoPoint(f(x%+1,1),(x%+1)*h/(n2%+1),0,c2%-dc%,vb%)
  
  PROCDoPoint(f(x%,2),x%*h/(n2%+1),0,c1%,vb%)
  PROCDoPoint(f(x%+1,1),(x%+1)*h/(n2%+1),0,c2%-dc%,vb%)
  PROCDoPoint(f(x%+1,2),(x%+1)*h/(n2%+1),0,c1%-dc%,vb%)
NEXT x%
SYS!(!B%+48),B%:REM pVB::Unlock
ENDPROC
:
DEFPROCDoPoint(x,y,z,c%, RETURN vb%)
REM Here are the coordinates of the point
!vb%=FN_f4(x)
vb%!4=FN_f4(y)
vb%!8=FN_f4(z)
REM Add normals. Assume all points are flat in the plane,so normal faces towards Z
vb%!12=FN_f4(0.0)
vb%!16=FN_f4(0.0)
vb%!20=FN_f4(1.0)
REM Now the colour
vb%!24=c%
vb%+=28  :REM Update pointer. I do it here so it's easy to change if you change the vertex size
ENDPROC
:
DEF PROCcleanup(nbufs%) : REM From example, slightly amended to allow for multiple buffers
LOCAL x%
FOR x%=0 TO nbufs%
  t%(nbufs%) += 0:IF t%(nbufs%) PROC_release(t%(nbufs%))
  b%(nbufs%) += 0:IF b%(nbufs%) PROC_release(b%(nbufs%))
  b%(nbufs%) += 0:IF b%(nbufs%) PROC_release(b%(nbufs%))
NEXT x%
d% += 0   :IF d%    PROC_release(d%)
ENDPROC
 
User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 29
xx Re: Quest for fire library (group effort )
« Reply #18 on: Jan 12th, 2018, 10:24am »

...and here's (an improved) version of the Logs program that doesn't need Make3dLib (the relevant sections are included).

Richard: thanks for your comments about using @dir$, which I will try to note and apply - especially in something like a library. However, I haven't changed it here, because the program is generating a file which will be used by another program. So your comment is important, in that it illustrates that this program (and its output file logs.fvf) will need to be in the same directory as the "flames" program (which will load the logs file from its host directory). I guess one solution might be to amend the routine to open a file save box, so the user can choose where to put it.

In the case of this type of program, which is going to be used essentially during a development phase, I think it DOES make sense to have things working in the same directory. Obviously in a finished "package" it would make sense to put all FVF files etc into a resource directory relative to the running program.

Best wishes,

D
Code:
REM Version of Logs with routines from Make3dLib included
nf%=8
maxverts%=FNGetNumVerts("Cylinder",nf%,1,nf%,TRUE)
DIM v(maxverts%-1,2),n(maxverts%-1,2),t(maxverts%-1,1)
totalverts%=3*FNGetNumVerts("Cylinder",nf%,1,nf%,TRUE)
vf%=&52
f%=FNOpenFVF("logs",totalverts%,vf%)

nv%=FNGetNumVerts("cylinder",nf%,1,nf%,TRUE)
PROCMake3D_Cylinder(nf%,v(),n(),t(),1,nf%,TRUE,0.0,1.0,0.0,1.0)
PROCStretch(nv%,v(),2,0.3,0.3)
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FF403510,&FFF0F0F0)

nv%=FNGetNumVerts("cylinder",nf%,1,nf%,TRUE)
PROCMake3D_Cylinder(nf%,v(),n(),t(),1,nf%,TRUE,0.0,1.0,0.0,1.0)
PROCStretch(nv%,v(),2,0.3,0.3)
PROCRotate(v(),0,0,PI/8)
PROCRotate(n(),0,0,PI/8)
PROCShift(v(),0.1,0.5,-0.5,nv%)
PROCShift(n(),0.1,0.5,-0.5,nv%)
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FF403510,&FFF0F0F0)

nv%=FNGetNumVerts("cylinder",nf%,1,nf%,TRUE)
PROCMake3D_Cylinder(nf%,v(),n(),t(),1,nf%,TRUE,0.0,1.0,0.0,1.0)
PROCStretch(nv%,v(),2,0.3,0.3)
PROCRotate(v(),0,-PI/8,-PI/8)
PROCRotate(n(),0,-PI/8,-PI/8)
PROCShift(v(),0.1,-0.5,0.5,nv%)
PROCShift(n(),0.1,-0.5,0.5,nv%)
PROCExtendFVF(f%,vf%,nv%,v(),n(),t(),&FF403510,&FFF0F0F0)

PROCCloseFVF(f%)
END
:
DEFFNGetNumVerts(n$,nf%,startface%,endface%,capped%)
LOCAL nv%,vpf%
PROCUpcase(n$)
CASE n$ OF
  WHEN "CYLINDER","PRISM","TRUNCCONE":
    IF capped% THEN vpf%=12 ELSE vpf%=6
    nv%=vpf%*(endface%-startface%+1)
  WHEN "SPHERE":
    nv%=(endface%-startface%+1)*2*nf% *6
    IF startface%=1 THEN nv%-=nf%*6
    IF endface%=nf% THEN nv%-=nf%*6
  WHEN "CONE":
    IF capped% THEN vpf%=6 ELSE vpf%=3
    nv%=vpf%*(endface%-startface%+1)
ENDCASE
=nv%
:
DEFPROCMake3D_Cylinder(nf%,v(),vn(),t(),startface%,endface%,capped%,texminu,texmaxu,texminv,texmaxv):Make3dLibNormals%=TRUE
LOCAL r,r2
r=1
r2=1
LOCAL vpf%,nv%,l,tdu,tdv,a,pa,py,pz,py2,pz2,ey,ez,ey2,ez2,ny,nz,ny2,nz2,eny,enz,eny2,enz2
IF capped% THEN vpf%=12 ELSE vpf%=6
nv%=vpf%*(endface%-startface%+1)
l=1
tdu=texmaxu-texminu
tdv=texmaxv-texminv
FOR a=0 TO endface%-startface%
  pa=a+startface%-1
  py=r*SIN(pa*2*PI/nf%)
  pz=r*COS(pa*2*PI/nf%)
  py2=r*SIN((pa+1)*2*PI/nf%)
  pz2=r*COS((pa+1)*2*PI/nf%)
  ey=r2*SIN(pa*2*PI/nf%)
  ez=r2*COS(pa*2*PI/nf%)
  ey2=r2*SIN((pa+1)*2*PI/nf%)
  ez2=r2*COS((pa+1)*2*PI/nf%)
  v(a*vpf%,0)=0
  v(a*vpf%,1)=py
  v(a*vpf%,2)=pz
  v(a*vpf%+1,0)=l
  v(a*vpf%+1,1)=ey2
  v(a*vpf%+1,2)=ez2
  v(a*vpf%+2,0)=l
  v(a*vpf%+2,1)=ey
  v(a*vpf%+2,2)=ez
  v(a*vpf%+3,0)=0
  v(a*vpf%+3,1)=py
  v(a*vpf%+3,2)=pz
  v(a*vpf%+4,0)=0
  v(a*vpf%+4,1)=py2
  v(a*vpf%+4,2)=pz2
  v(a*vpf%+5,0)=l
  v(a*vpf%+5,1)=ey2
  v(a*vpf%+5,2)=ez2
  IF Make3dLibNormals% THEN
    ny=(r+1)*SIN(pa*2*PI/nf%)
    nz=(r+1)*COS(pa*2*PI/nf%)
    ny2=(r+1)*SIN((pa+1)*2*PI/nf%)
    nz2=(r+1)*COS((pa+1)*2*PI/nf%)
    eny=(r2+1)*SIN(pa*2*PI/nf%)
    enz=(r2+1)*COS(pa*2*PI/nf%)
    eny2=(r2+1)*SIN((pa+1)*2*PI/nf%)
    enz2=(r2+1)*COS((pa+1)*2*PI/nf%)
    vn(a*vpf%,0)=0
    vn(a*vpf%,1)=ny
    vn(a*vpf%,2)=nz
    vn(a*vpf%+1,0)=l
    vn(a*vpf%+1,1)=eny2
    vn(a*vpf%+1,2)=enz2
    vn(a*vpf%+2,0)=l
    vn(a*vpf%+2,1)=eny
    vn(a*vpf%+2,2)=enz
    vn(a*vpf%+3,0)=0
    vn(a*vpf%+3,1)=ny
    vn(a*vpf%+3,2)=nz
    vn(a*vpf%+4,0)=0
    vn(a*vpf%+4,1)=ny2
    vn(a*vpf%+4,2)=nz2
    vn(a*vpf%+5,0)=l
    vn(a*vpf%+5,1)=eny2
    vn(a*vpf%+5,2)=enz2
  ENDIF
  t(a*vpf%,0)=texminu
  t(a*vpf%,1)=texminv+tdv*pa/nf%
  
  t(a*vpf%+1,0)=texmaxu
  t(a*vpf%+1,1)=texminv+tdv*(pa+1)/nf%
  
  t(a*vpf%+2,0)=texmaxu
  t(a*vpf%+2,1)=texminv+tdv*pa/nf%
  
  t(a*vpf%+3,0)=texminu
  t(a*vpf%+3,1)=texminv+tdv*pa/nf%
  
  t(a*vpf%+4,0)=texminu
  t(a*vpf%+4,1)=texminv+tdv*(pa+1)/nf%
  
  t(a*vpf%+5,0)=texmaxu
  t(a*vpf%+5,1)=texminv+tdv*(pa+1)/nf%
  IF capped% THEN
    v(a*vpf%+6,0)=0
    v(a*vpf%+6,1)=py
    v(a*vpf%+6,2)=pz
    v(a*vpf%+7,0)=0
    v(a*vpf%+7,1)=0
    v(a*vpf%+7,2)=0
    v(a*vpf%+8,0)=0
    v(a*vpf%+8,1)=py2
    v(a*vpf%+8,2)=pz2
    v(a*vpf%+9,0)=l
    v(a*vpf%+9,1)=ey
    v(a*vpf%+9,2)=ez
    v(a*vpf%+10,0)=l
    v(a*vpf%+10,1)=0
    v(a*vpf%+10,2)=0
    v(a*vpf%+11,0)=l
    v(a*vpf%+11,1)=ey2
    v(a*vpf%+11,2)=ez2
    IF Make3dLibNormals% THEN
vn(a*vpf%+6,0)=-10
vn(a*vpf%+6,1)=py
vn(a*vpf%+6,2)=pz
vn(a*vpf%+7,0)=-10
vn(a*vpf%+7,1)=0
vn(a*vpf%+7,2)=0
vn(a*vpf%+8,0)=-10
vn(a*vpf%+8,1)=py2
vn(a*vpf%+8,2)=pz2
vn(a*vpf%+9,0)=l+10
vn(a*vpf%+9,1)=ey2
vn(a*vpf%+9,2)=ez2
vn(a*vpf%+10,0)=l+10
vn(a*vpf%+10,1)=0
vn(a*vpf%+10,2)=0
vn(a*vpf%+11,0)=l+10
vn(a*vpf%+11,1)=ey2
vn(a*vpf%+11,2)=ez2
    ENDIF
    t(a*vpf%+6,0)=texminu
    t(a*vpf%+6,1)=texminv+tdv*a/nf%
    t(a*vpf%+7,0)=texminu+tdu/2
    t(a*vpf%+7,1)=texminv+tdv/2
    t(a*vpf%+8,0)=texminu
    t(a*vpf%+8,1)=texminv+tdv*(a+1)/nf%
    t(a*vpf%+9,0)=texmaxu
    t(a*vpf%+9,1)=texminv+tdv*a/nf%
    t(a*vpf%+10,0)=texminu+tdu/2
    t(a*vpf%+10,1)=texminv+tdv/2
    t(a*vpf%+11,0)=texmaxu
    t(a*vpf%+11,1)=texminv+tdv*(a+1)/nf%
  ENDIF
NEXT a
ENDPROC
:
DEFPROCRotate(a(),xa,ya,za)
LOCAL xrm(),yrm(),zrm()
DIM xrm(2,2),yrm(2,2),zrm(2,2)
xrm()=1,0,0,0,COS(xa),-SIN(xa),0,SIN(xa),COS(xa)
yrm()=COS(ya),0,SIN(ya),0,1,0,-SIN(ya),0,COS(ya)
zrm()=COS(za),-SIN(za),0,SIN(za),COS(za),0,0,0,1
xrm()=xrm().yrm()
xrm()=xrm().zrm()
a()=a().xrm()
ENDPROC
:
DEFPROCShift(a(),dx,dy,dz,nv%)
LOCAL x%
FOR x%=0 TO nv%-1
  a(x%,0)+=dx
  a(x%,1)+=dy
  a(x%,2)+=dz
NEXT x%
ENDPROC
:
DEFPROCStretch(nv%,v(),xf,yf,zf)
LOCAL x%
FOR x%=0 TO nv%-1
  v(x%,0)*=xf
  v(x%,1)*=yf
  v(x%,2)*=zf
NEXT x%
ENDPROC
:
DEFFNOpenFVF(name$,nv%,vf%)
LOCAL f%,vs%
vs%=0
IF vf% AND 2 THEN vs%+=12
IF vf% AND &10 THEN vs%+=12
IF vf% AND &40 THEN vs%+=4
IF vf% AND &80 THEN vs%+=4
IF vf% AND &100 THEN vs%+=8
REM Create file and fill it with data
f%=OPENOUT(@dir$+name$+".FVF")
PROC4(f%,nv%)
PROC4(f%,(vs%<<16)+vf%)
=f%
:
DEFPROCCloseFVF(f%)
CLOSE #f%
ENDPROC
:
DEFPROCExtendFVF(f%,vf%,nv%,vdat(),ndat(),tdat(),acol%,scol%)
LOCAL x%
FOR x%=0 TO nv%-1
  IF vf% AND 2 THEN PROC4(f%,FN_f4(vdat(x%,0))):PROC4(f%,FN_f4(vdat(x%,1))):PROC4(f%,FN_f4(vdat(x%,2)))
  IF vf% AND &10 THEN PROC4(f%,FN_f4(ndat(x%,0))):PROC4(f%,FN_f4(ndat(x%,1))):PROC4(f%,FN_f4(ndat(x%,2)))
  IF vf% AND &40 THEN PROC4(f%,acol%)
  IF vf% AND &80 THEN PROC4(f%,scol%)
  IF vf% AND &100 THEN PROC4(f%,FN_f4(tdat(x%,0))):PROC4(f%,FN_f4(tdat(x%,1)))
NEXT x%
ENDPROC
:
DEFPROCUpcase(RETURN n$)
LOCAL x%
FOR x%=1 TO LEN(n$)
  IF ASC(MID$(n$,x%,1))>96 AND ASC(MID$(n$,x%,1))<123 THEN n$=LEFT$(n$,x%-1)+CHR$(ASC(MID$(n$,x%,1))-32)+MID$(n$,x%+1)
NEXT x%
ENDPROC
:
REM Stolen from Richard's D3D demo
DEF PROC4(F%, A%)
BPUT#F%,A% : BPUT#F%,A%>>8 : BPUT#F%,A%>>16 : BPUT#F%,A%>>24
ENDPROC
:
REM Stolen from Richard's D3D library
DEF FN_f4(A#)
LOCAL A%,P%,U#
PRIVATE F%
IF F%=0 THEN
  DIM P% 10
  [OPT 2
  .F%
  mov esi,[ebp+2]:mov edi,[ebp+7]
  fld qword [esi]:fstp dword [edi]
  ret
  ]
ENDIF
!(^U#+4)=&3FF00000
A#*=U#
CALL F%,A#,A%
=A%
 
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Quest for fire library (group effort )
« Reply #19 on: Jan 12th, 2018, 11:41am »

on Jan 12th, 2018, 10:14am, DDRM wrote:
It turns out the order you render the buffers is critical: if you want things to show through, they need to have been rendered first

That surprises me. I would have expected the Z-buffer to be the determining factor, i.e. I would have expected that a 'foreground' object, with or without transparency, would always appear 'in front of' a background object, irrespective of the order in which they are specified in the list of buffers. Otherwise it would imply that you need to change the buffer order depending on the viewpoint, which surely can't be right?

I wonder if you have fallen into the same trap as I did, briefly, when making the BBC OWL simulation. That is, to assume that the Z-buffer has 'infinite' depth resolution, which of course it doesn't because the values stored are only 32-bit floats (if that). The implication is that you need to ensure that two objects (in my case they were concentric spheres) are sufficiently separated that there will be no ambiguity about which is 'in front'. If their depths are too similar they may round to the same value in the Z-buffer and then I could believe that the order in which they are specified does indeed matter.

Quote:
However, I haven't changed it here, because the program is generating a file which will be used by another program.

I don't think that, in itself, makes a difference because (for example) @tmp$ points to the same location in all BB4W programs so a file created there by one will be visible to another.

What perhaps you really mean is that your library is intended to be a developers' library, i.e. that rather being installed from a deployed application at run time you expect it to be used by a developer to build that application (or, to be more precise, files used by the application).

That's not something I have ever come across before, but if it is the case I would say that (1) you need to make it very clear, because it's so out of the ordinary and (2) you need to check for the file creation having failed and generate a 'helpful' message rather than throwing a generic error.

Richard.
User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 29
xx Re: Quest for fire library (group effort )
« Reply #20 on: Jan 12th, 2018, 12:41pm »

Hi Richard,

What I saw was that the Z position correctly controlled which was drawn in front of the other (I agree very small Z differences don't always work quite as you expect) - and indeed, the flames can render BETWEEN the logs if you position it right - but that when the flames were rendered in front of the logs (but before the logs themselves had been rendered) you couldn't see the logs through them. When you render the logs first, then the flames, you CAN see through them to the logs behind. I can imagine that it's problematic for D3D to realise that something it's already dealt with is transparent, and the new thing it's rendering behind it should be partially rendered with it. I guess the moral of the story is "render transparent things last".

With regard to directories, I agree that library functions need, by default, to save somewhere sensible (and writable!) I rather assumed that the dir$ active at the time relates to the program calling the library - is that not the case? Nonetheless, your point is well made that I can't assume that a program will be running from a writable directory. I wasn't thinking about a "development library", but that the programs using it will be for creating resources (FVF files) as part of the development process: typically I keep all such "helper" programs, together with working resource files, together in one folder (in this case, called D3D), but obviously not everyone works the same way!

Does getting the routine in the library to open a "save as" box seem a reasonable solution? I'm not keen on using temp$ or usr$ because (a) the user may not know where they are, and be unable to find the file, and (b) don't you have to assume that things in the temp directory can be deleted when this use is finished? I don't think Windows does automated garbage collection in the way Android does, but my understanding was that you shouldn't rely on things staying in the temp directory for long... Maybe I'm very old-fashioned in this, as I think you've suggested before wink

Best wishes,

D
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 689
xx Re: Quest for fire library (group effort )
« Reply #21 on: Jan 12th, 2018, 3:56pm »

on Jan 12th, 2018, 12:41pm, DDRM wrote:
I rather assumed that the dir$ active at the time relates to the program calling the library - is that not the case?

I'm not sure what you mean by "relates to" in this sense. @dir$ is initialised to point to the directory from which the program was originally loaded, if that is known. If the program was pasted in (or typed, or dropped) then of course that isn't known - indeed the program may not be saved at all - in which case @dir$ cannot be relied upon to point to anywhere specific.

That was the case when I received the 'Invalid channel' error: I had pasted your program from the forum but had not saved it. As a result @dir$ pointed to the EXAMPLES folder of the BB4W installation (under C:\Program Files (x86)\BBC BASIC) which is definitely not writable unless 'run as' elevated.

Quote:
Does getting the routine in the library to open a "save as" box seem a reasonable solution?

I don't think I've entirely understood the possible usage cases. If the purpose of the library is for a software developer to create an FVF file, which he will eventually ship with his program, then he will be wanting to create it in @dir$ or a sub-directory thereof. If it's intended that the library itself be shipped with the program, so that the FVF file is created 'on the fly' at run time, then it will need to be created in @tmp$.

In the former case I suppose it would be acceptable to open a file selector, but not in the latter case. For all I know you may intend that the library can be used in both these scenarios. The only fully flexible approach, I would have thought, is for the path/filename to be supplied as a parameter and not determined by the library at all. Indeed, looking at your code, why does the library decide the directory and extension when these could simply be passed in the name$ parameter?

Finally, I'd recommend that you replace the old CPU-dependent version of FN_f4 (which uses x86 assembler code) with the entirely-BASIC version listed below. Not only is it CPU-agnostic, benchmarking showed it to be faster (you may remember that I posted an earlier version to the discussion group as a challenge to see if anybody could improve on it).

Richard.

Code:
      REM Convert to 4-byte float
      DEF FN_f4(a#)LOCALP%:P%=^a#:IFABSa#<1E-38THEN=FALSE
      =P%!4ANDNOT&7FFFFFFFOR(P%!4-&38000000<<3OR!P%>>29AND7)+(!P%>>28AND1) 

« Last Edit: Jan 12th, 2018, 3:58pm by Richard Russell » User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 29
xx Re: Quest for fire library (group effort )
« Reply #22 on: Jan 15th, 2018, 08:13am »

Hi Richard,
Quote:
Indeed, looking at your code, why does the library decide the directory and extension when these could simply be passed in the name$ parameter?


Quote:
MAJIKTHISE:
Bloody ‘ell! That’s what I call thinking! Here Vroomfondel, why do we never think of things like that?

VROOMFONDEL:
Dunno. Think our minds must be too highly trained Majikthise

Duh, yes, that would be much more sensible... I'll change it.

Thanks also for the updated version of FN_f4

Best wishes,

D
User IP Logged

michael
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 141
xx Re: Quest for fire library (group effort )
« Reply #23 on: Jan 17th, 2018, 12:44am »

The 3D fire is pretty cool.
User IP Logged

I like reinventing the wheel, but for now I will work on tools for D3D
Pages: 1 2  Notify Send Topic Print
« Previous Topic | Next Topic »

Donate $6.99 for 50,000 Ad-Free Pageviews!


This forum powered for FREE by Conforums ©
Sign up for your own Free Message Board today!
Terms of Service | Privacy Policy | Conforums Support | Parental Controls