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

Welcome Guest. Please Login or Register.
Mar 31st, 2018, 11:12pm



ATTENTION MEMBERS: Conforums will be closing it doors and discontinuing its service on April 15, 2018.
We apologize Conforums does not have any export functions to migrate data.
Ad-Free has been deactivated. Outstanding Ad-Free credits will be reimbursed to respective payment methods.

Thank you Conforums members.
Cross-platform BBC BASIC (Windows, Linux x86, Mac OS-X, Android, iOS, Raspberry Pi)
BBC BASIC Resources
BBC BASIC Help Documentation
BBC BASIC for Windows Home Page
BBC BASIC Programmers' Reference
BBC BASIC Beginners' Tutorial
BBC BASIC for SDL 2.0 Home Page
BBC BASIC Discussion Group

« Previous Topic | Next Topic »
Pages: 1 2  Notify Send Topic Print
 hotthread  Author  Topic: Quest for fire library (group effort )  (Read 675 times)
michael
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 157
xx Re: Quest for fire library (group effort )
« Reply #3 on: Dec 28th, 2017, 12:23am »

That's very nice. David Williams contributed quite a few samples also..

I think perhaps a resizable fire for dungeons would be an asset..

As I recall, fire has been a huge part of pretty well any game that involves adventure or role play or multiplayer role play. Fire could make a dungeon made with lines have depth and feeling.

User IP Logged

I like reinventing the wheel, but for now I will work on tools for D3D
Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 803
xx Re: Quest for fire library (group effort )
« Reply #4 on: Dec 28th, 2017, 11:49am »

on Dec 28th, 2017, 12:23am, michael wrote:
I think perhaps a resizable fire for dungeons would be an asset..

I'm not too sure how it could be any more 'resizable' than it is now, given that the last two parameters of the *mdisplay or PROCrender calls are the width and height! Can you explain?

Richard.



Code:
          OSCLI "mdisplay " + STR$~BMP{} + " 140,100,256,512"          OSCLI "mdisplay " + STR$~BMP{} + " 450,315,192,384"          OSCLI "mdisplay " + STR$~BMP{} + " 680,480,144,288"          OSCLI "mdisplay " + STR$~BMP{} + " 860,600,108,216"          OSCLI "mdisplay " + STR$~BMP{} + " 990,690,81,162" 
« Last Edit: Dec 28th, 2017, 12:58pm by Richard Russell » User IP Logged

michael
Full Member
ImageImageImage


member is offline

Avatar




PM


Posts: 157
xx Re: Quest for fire library (group effort )
« Reply #5 on: Dec 28th, 2017, 2:07pm »

Oh... I see. I will experiment with that. Thanks Richard.
User IP Logged

I like reinventing the wheel, but for now I will work on tools for D3D
DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 36
xx Re: Quest for fire library (group effort )
« Reply #6 on: Jan 2nd, 2018, 1:50pm »

I had a play with this. I make no claims that it is any better than previous offerings...

Seems to run OK in BB4W and in BBC_SDL, though rather slower in the latter - you might want to change the WAIT to 5, or even 1.

I have thought about converting it to use D3D (or equivalent): then you could blend colours for the triangles, and make them semi-transparent, so you could see the firewood through them. I'm not sure what will happen if I try to rewrite the vertex buffers dynamically - it may cause a spectacular crash... Does anyone know?

Best wishes,

D
Code:
            MODE 21      *REFRESH OFF      GCOL 3      FOR duration%=0 TO 100        CLS        PROCDrawLog(180,420,-30,100,320)        PROCDrawLog(200,370,0,80,340)        PROCDrawLog(240,330,30,90,320)        PROCDrawFlame(430,420,210,500)        PROCDrawFlame(300,400,210,400)        PROCDrawFlame(500,400,210,400)        PROCDrawFlame(400,300,210,300)          PROCDrawLog(780,420,-30,30,120)        PROCDrawLog(800,370,0,25,140)        PROCDrawLog(840,330,30,30,120)        PROCDrawFlame(830,420,50,70)        PROCDrawFlame(800,400,50,70)        PROCDrawFlame(900,400,50,70)        PROCDrawFlame(850,350,50,85)        *REFRESH        WAIT 10      NEXT duration%      *REFRESH ON      END      :      DEFPROCDrawLog(px%,py%,a%,w%,l%)      COLOUR 3,50,30,0      MOVE px%,py%      MOVE px%+w%*COSRAD(a%+90),py%+w%*SINRAD(a%+90)      PLOT 117,px%+l%*COSRAD(a%)+w%*COSRAD(a%+90),py%+l%*SINRAD(a%)+w%*SINRAD(a%+90)      ENDPROC      :      DEFPROCDrawFlame(px%,py%,w%,h%)      LOCAL x%,hw%,dw%,dh%,f%()      DIM f%(26,2)      hw%=w%/2      dw%=hw%*0.8      dh%=h%/25      FOR x%=0 TO 25        f%(x%,1)=px%+RND(x%)        f%(x%,0)=f%(x%,1)-hw%+ABS(dw%-dw%*SQR(x%)/2.5)+RND(x%)*hw%/100        f%(x%,2)=f%(x%,1)+hw%-ABS(dw%-dw%*SQR(x%)/2.5)-RND(x%)*hw%/100      NEXT x%      f%(26,1)=px%+RND(x%)      f%(26,0)=f%(26,1)      f%(26,2)=f%(26,1)      GCOL 3      FOR x%=0 TO 25        COLOUR 3,200+x%,150-2*x%,26-x%        MOVE f%(x%,1),x%*dh%+py%        MOVE f%(x%+1,1),(x%+1)*dh%+py%        PLOT 85,f%(x%,0),x%*dh%+py%        PLOT 85,f%(x%+1,0),(x%+1)*dh% +py%        MOVE f%(x%,1),x%*dh%+py%        MOVE f%(x%+1,1),(x%+1)*dh%+py%        PLOT 85,f%(x%,2),x%*dh%+py%        PLOT 85,f%(x%+1,2),(x%+1)*dh%+py%          COLOUR 3,220+x%,220-2*x%,70-x%        MOVE f%(x%,1),x%*dh%+py%        MOVE f%(x%+1,1),(x%+1)*dh%+py%        PLOT 85,(f%(x%,0)+f%(x%,1))/2,x%*dh%+py%        PLOT 85,(f%(x%+1,0)+f%(x%+1,1))/2,(x%+1)*dh% +py%        MOVE f%(x%,1),x%*dh%+py%        MOVE f%(x%+1,1),(x%+1)*dh%+py%        PLOT 85,(f%(x%,2)+f%(x%,1))/2,x%*dh%+py%        PLOT 85,(f%(x%+1,2)+f%(x%+1,1))/2,(x%+1)*dh% +py%      NEXT x%      ENDPROC 
« Last Edit: Jan 2nd, 2018, 2:13pm by DDRM » User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 803
xx Re: Quest for fire library (group effort )
« Reply #7 on: Jan 2nd, 2018, 8:12pm »

on Jan 2nd, 2018, 1:50pm, DDRM wrote:
I had a play with this. I make no claims that it is any better than previous offerings...

I'd call it a 'flame' rather than a 'fire' I think.

Quote:
Seems to run OK in BB4W and in BBC_SDL, though rather slower in the latter

Interesting: it runs slightly faster in BBCSDL than in BB4W on this laptop (about 10% CPU for BBCSDL and 11% for BB4W). That makes me suspect that the OpenGL acceleration on your PC isn't all that hot, which is a shame because it's going to hit BBCSDL graphics performance across the board.

Richard.
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 803
xx Re: Quest for fire library (group effort )
« Reply #8 on: Jan 3rd, 2018, 11:38am »

on Jan 2nd, 2018, 1:50pm, DDRM wrote:
Seems to run OK in BB4W and in BBCSDL, though rather slower in the latter

Silly question (I hope): when comparing speeds can I assume you are running the latest versions of both (6.11a and 0.19b respectively)?

Richard.
User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 36
xx Re: Quest for fire library (group effort )
« Reply #9 on: Jan 3rd, 2018, 3:18pm »

Hi Richard,

Assuming it might be rash, but in this case it is true... grin

When I say it "runs slower", I didn't look at the CPU usage, or frame rate or anything, just a subjective impression that the "flickering" was more laboured.

Your comment about OpenGL acceleration is probably pertinent: it's an oldish corporate PC, and I doubt if pushing the latest OpenGL drivers is high on their list of priorities...

Best wishes,

D
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 803
xx Re: Quest for fire library (group effort )
« Reply #10 on: Jan 3rd, 2018, 4:16pm »

on Jan 3rd, 2018, 3:18pm, DDRM wrote:
I didn't look at the CPU usage, or frame rate or anything, just a subjective impression that the "flickering" was more laboured.

You have to be careful what you are comparing because your program uses *REFRESH, which works differently in BB4W and BBCSDL. In BB4W *REFRESH is an asynchronous command which simply sets a flag to tell Windows to update the display when it next 'gets around to it' (Windows doesn't synchronise its update with the display refresh unless you do it yourself using e.g. Direct Draw).

In BBCSDL, on the other hand, *REFRESH is a synchronous command which waits until the next display refresh (vertical sync) before returning. So, typically, it's necessary in BB4W to include a WAIT statement to prevent a program gobbling up 100% CPU, whereas in BBCSDL it waits in *REFRESH (whether it waits efficiently, with low CPU usage, or busy-waits with high CPU usage is a function of the platform and its drivers, and is out of your control).

So my cross-platform programs tend to have a code snippet such as this:

Code:
      IF INKEY$(-256)="W" WAIT 2      *REFRESH 

Richard.
User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 36
xx Re: Quest for fire library (group effort )
« Reply #11 on: Jan 4th, 2018, 08:30am »

Thanks, Richard, that is both interesting and useful!

Best wishes,

D
User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


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

Hi Folks,

Well, I did have a go at doing it in D3D. It's proved harder than I hoped to get nice transparency effects - I can't seem to get it to show the logs through the flames, for example, and I don't think I understand emissivity properly! Anyway, I think the Gouraud shading makes the flames look quite nice, and they DO overlap each other...

Here's the code for the "flames" bit. It requires an FVF file for the logs: I'll post code for that separately in a moment.

At the moment this is written specifically for BB4W, and Windows, since it uses a number of D3D SYS calls. I don't know how to do the equivalent in SDL, but I'd be interested to see a conversion! I presume a lot of the stuff with FVF buffers should be fairly straightforward to convert.

Best wishes,

D
Code:
      HIMEM=LOMEM+1E8      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%(nbufs%), 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 David's attempt to 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)      REM Set up vertex buffers for each flame      FOR x%=0 TO nbufs%-1        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%      REM Set up vertex buffer by loading the background "scene" - here it's just 3 logs!      b%(nbufs%)=FN_load3d(d%,"logs.fvf",n%(nbufs%),f%(nbufs%),s%(nbufs%))      IF b%(nbufs%)=0 THEN PROCcleanup(nbufs%):PRINT "Logs failed to load!":END      X(nbufs%)=-0.5      Z(nbufs%)=0.8      p() = 0    :REM No pan/roll/yaw - could be omitted!      r() = 0      y()=0      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%=0 TO nbufs%-1          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 may need to increase the memory reserved at the beginning, or it will crash!      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)      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<<24)        c2%=((190+x%)<<16)+((158-x%)<<8)+55-x%  +(&80<<24)        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 Now need 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: 36
xx Re: Quest for fire library (group effort )
« Reply #13 on: Jan 11th, 2018, 09:04am »

Here's the code for the logs: you'll need my Make3DLib, which I actually keep in my D3D folder: amend the INSTALL address accordingly.

Make3DLib is available in the files area on the groups.io site: if you give me a couple of minutes I'll update the version there to make sure it is the current one.

Best wishes,

D
Code:
      INSTALL "Make3DLib"      nf%=6      maxverts%=FNGetNumVerts("Cylinder",nf%,1,nf%,TRUE)      DIM v(maxverts%-1,2),n(maxverts%-1,2),t(maxverts%-1,1)      nf%=6      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)      PROCFindNormals(nv%,v(),n())      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)      PROCFindNormals(nv%,v(),n())      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)      PROCFindNormals(nv%,v(),n())      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 
User IP Logged

Richard Russell
Administrator
ImageImageImageImageImage


member is offline

Avatar




Homepage PM


Posts: 803
xx Re: Quest for fire library (group effort )
« Reply #14 on: Jan 11th, 2018, 1:02pm »

on Jan 11th, 2018, 08:48am, DDRM wrote:
I don't know how to do the equivalent in SDL

SDL is 2D only (I assume you're relying on the third dimension, otherwise you wouldn't be using D3DLIB - unless you want it solely for transparency in which case GDIPlus might be easier).

For 3D stuff in BBCSDL you need to use OpenGL (which is generally more straightforward than Direct3D because of the 'flat' interface); there's no shortage of documentation online. For enabling alphablending you can look at 'bbcowl.bbc' which relies on it I think.

Mind you I'm not sure that you will find a direct OpenGL equivalent of 'set emissive materialcoloursource to "diffuse vertex colour"' (without coding a shader) - and Google doesn't help.

Richard.
« Last Edit: Jan 11th, 2018, 1:05pm by Richard Russell » User IP Logged

DDRM
Global Moderator
ImageImageImageImageImage


member is offline

Avatar




PM


Posts: 36
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: 803
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: 36
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 21nbufs%=4REM Here I'm actually reserving arrays 1 BIGGER than nbufs% (i.e. 0 - nbufs%), which gives me one for background scene - here, the logsDIM 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%):QUITON ERROR PROCcleanup(nbufs%):PRINT REPORT$:ENDd% = FN_initd3d(@hwnd%, 1, 1)IF d% = 0 ERROR 100, "Can't initialise Direct3D"REM Set alpha blendingSYS !(!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) 103l%(0)!0 = 3 : REM directional light, taken from manual (parameters adjusted)l%(0)!4 = FN_f4(1)  : REM red componentl%(0)!8 = FN_f4(1)  : REM green componentl%(0)!12 = FN_f4(1) : REM blue componentl%(0)!64 = FN_f4(0.5) : REM. X component of directionl%(0)!68 = FN_f4(-0.50) : REM. Y component of directionl%(0)!72 = FN_f4(0.2) : REM. Z component of directionnv%=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!":ENDX(0)=-0.2Y(0)=0.3Z(0)=0.8REM Set up vertex buffers for each flameFOR 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!":ENDNEXT x%e() = 0,0,-10  :REM Eye/camera positiona() = 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 10NEXT 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 CreateVertexBufferIF 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 flamen2%=n%^2hn=n%/2DIM f(n2%+1,2)hw=w/2dw=hw*0.8FOR 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 bufferSYS!(!B%+44),B%,0,N%*L%,^P%,0:REM pVB::Lockvb%=P%  :REM vb% is a pointer to where we have got to in the bufferdc%=(1<<16)-(2<<8)-1 :REM calculate difference in colour for one level higherFOR 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::UnlockENDPROC: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 Zvb%!12=FN_f4(0.0)vb%!16=FN_f4(0.0)vb%!20=FN_f4(1.0)REM Now the colourvb%!24=c%vb%+=28  :REM Update pointer. I do it here so it's easy to change if you change the vertex sizeENDPROC:DEF PROCcleanup(nbufs%) : REM From example, slightly amended to allow for multiple buffersLOCAL 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

Pages: 1 2  Notify Send Topic Print
« Previous Topic | Next Topic »

| |

This forum powered for FREE by Conforums ©
Terms of Service | Privacy Policy | Conforums Support | Parental Controls