Main Menu

PlayBasic2DLL Questions?

Started by ScottieB, August 13, 2016, 05:37:35 AM

Previous topic - Next topic

kevin

#15
QuoteI get the moveing of sin/cos correctly.
Not understanding the tiles thing though?  I need to store information (arrays) for 3d-projection later.  Did'nt know CPU's didn't like this as I thoought most programmers used theses while programming.  But I still would like to understand what tiles are about?  Sounds like a pixel average.  still how's that going to be stored for later use?

    Reading from memory is slow, very slow..  So CPU's pull chunks from the memory in the various cache levels.  When  you read from memory it grabs more data that you request,  as it assumes they'll be needed.    This is fine when a routine is reading fields in a structurue for moving through memory in a linear fashion, but ray casting isn't linear.   So the wider the source texture the more cache hits you get.

   
Quote
Is there a way to make a loop that will do reading/writing from multiple maps? Or do I have to do each one separately? Like my above code I want height values then I want colour values each
from different maps but can this loop be reduced to one and still get both data from both maps?

   just compute the rays X/Y coord and then use that on both..  


Quote
I could probablyget rid of some arrays if I did'nt have to lock/unlock bufffers but I have to too use fastDot/fastpoint unless I can render elsewhere's as I read/write with them but that again
uses another image/screen that I have to write too.  So How can I approach this where I read/writeing all over the place?

  ???   I didn't follow any of that...  

   I'd would just use a bank to sort the texture/height maps, then compute offset to each pixel and read/write from the them..


PlayBASIC Code: [Select]
   Width   =2^9  ; 512 pixels
Height=Width


// compute the number of bytes useds in a single row of pixels
BytesPerRow = Width * 4 ; (32 bit colours are 4 bytes )

// make some mock up surfaces in banks
TextureIMageBank = NewBank(Height*BytesPerRow)
HeightMapIMageBank = NewBank(Height*BytesPerRow)



// --------------------------------------------------------
Do
// --------------------------------------------------------

cls $304070


CurrentDrawColour+= $1234



ca# =cos(Angle#)
sa# =sin(Angle#)

CameraX= mousex()
CameraY= mousey()

X=CameraX
Y=CameraY

lockbuffer
For Ray=0 to 100


// Compute next point
x=CameraX+(Ray*Ca#)
y=CameraY+(Ray*Sa#)

// wrap X / Y within legal space..
X= X and $1ff
Y= Y and $1ff

// compute position within the image bank array
// this is the offset from pixel 0,0 (top left)
Offset = (Y * BytesPerRow) + (X * 4)

// Read the from pretend Height Map
TerrainHeight = PeekBankInt(HeightMapImagebank, Offset)

// read from the pretend Image
TerrainRGB = PeekBankInt(TextureIMageBank, Offset)


// render a 32bit colour to the texture at this location
// just for something to look at
POkeBankInt TextureImageBank, Offset,CurrentDrawColour


next
unlockbuffer

// bump the angle
Angle#=wrapangle(angle#+2)


// --------------------------------------------------------
// Copy the the texture to screen row by row
// --------------------------------------------------------
lockbuffer

DestPtr = GetImagePtr(0)
DestModulo = GetImagePitch(0)

; get the pointer to the bank
SrcPtr =GetBankPtr(TextureImageBank)

; copy the rows of pixels from the bank
For ylp =0 to Height-1

; copy this row of pixels
CopyMemory SrcPtr,DestPtr, BytesPerRow

// Movec Src to the next row
SrcPtr +=BytesPerRow

// Move output to next row
DestPtr+=DestModulo
next
unlockbuffer




sync
loop






ScottieB

#16
That's a great solution for multiple maps.
Though in your code rays so be Ray length and I just have to add rays afterward because it's a nested loop.
But I get the picture now use bank statements to reach many maps at same time with one pass.
Thanks for pointing that out.
Kewl!

So, am I getting this right poke my colors from fastpoints into banks at start up and read them with peeks? So, this is an initialization phase and then I can read them all as wish or can I copy images directly into banks first?  i.e. copymemory image-bank in one big chunk i.e. size first?

Here's an uudate it's not finished by no means but now you can see what I'm trying to accomplish,  You now can see some sort of render/3d projection though it still can be better and
speeded up useing even wave surfing and it's still not clipped I was just working on getting it so you can see what I'm shooting for.

Though they will be columns for points with various height not pixels and distances are not perfect due to spherical distortion cause by sin/cos rays but your starting to see the output.
Question though Kevin I don't want to compute the distance formaulas inside the main loop do I???  So can they be pre-comuted for further speed enhancements?

kevin


the process of loading a load an image to a bank is basically the reverse of the previous example does, which copies the bank to the screen.   Swap the Src and Destinations and your copying the other way.  Expect you wouldn't do it from the screen, but rather the loaded image.   

ScottieB

#18
O.K.

Now here's a question?

How do I draw fast lines?  because voxels are goiing to be strips or columns and wave surfing is just this...

Ys Is my height of the initial strip at first height value then only heights higher will need to be drawn or continued above like say its 100 then anything
above 100 to come along down the ray that is higher than 100 like 150 then we continue up to 150 ect...

but...
I need to draw fast line or strips so how can I fill columns with a rgb colour fast in memory or image fast so then I can blast them to the screen????

Take a look at update of proggie.

You'll see what I mean.
The question is I guess really how to I further add more speed??? Speed it up more. See if you now can see anything that can.
I reduced distance formulas and Now have map wrap arround and better visuals.  See haveing problem with angle wraparound though and ideas on that too?
Thanks a bunch for the help with this one.


I sortof look like a floodfill but strips or quick line drawing from point to point.  That's the key point to point in column so a real fast line drawing with may heights so Y = 100 - 150 then 150 -200 ect... Or some kind of way to draw fast lines.

Oh, Got the clamping done now but still wondering about speed ups!!!!

Thanks
ScottieB

kevin

#19
  Looking good..  

 Drawing vertical/horizontal stip in memory boils down to a loop and where you have a pointer (the address of something in memory) the starting pixel and then you write a pixel (PokeInt), then add to the current pixel address..  For a left to right line,  you'd be adding the size of 1 32bit pixel (4).   For a line that's top to bottom, then between each pixels is the number of bytes per line.  So if  the target image is 800 pixels and is 32bit, then the bytes per row would be 800*4..  

eg

PixelAddress = (Address in memory starting pixel)
For Xlp = X1 To X2-1
  pokeInt PixelAddress,This_RGB_COLOUR
  PixelAddress+=4  ; move to mext pixel
next


or.

PixelAddress = (Address in memory starting pixel)
For Xlp = X1 To X2-1
  pokeInt PixelAddress,This_RGB_COLOUR
  PixelAddress+=BytePerRow   ; move to mext pixel on the row bellow the previous pixel
next


  There's few other unneeded calcs in the inner most loop,  like if rather than grabbing the R chan from the height and flipping it,  you can convert the height map up front, so whenyou pull the height, it's in the correct format.



         Ys = (Altitude - Player_Height) * Scaler / Distance# + (X_Screen_Res / 2)

  The  (X_Screen_Res / 2) should pre computed outside the inner loop.  
 
  Also, since the colour is only need when a strip is visible,  it'd be better to grab that inside the vertical clip.  

PlayBASIC Code: [Select]
          If Ys > Max_Height  

// Read colour of this point
TerrainRGB = PeekBankInt(TextureImageBank,Offset)

For Y = Max_Height To Ys
FastDot Rays,Y_Screen_Res - Y,TerrainRGB
Next Y

;lineC rays,Max_Height,rays,Ys,TerainRG
EndIf




        The clipping can be down with clip range.   Although You probably should a version Y_Screen_Res minus one, as the range clip is inclusive

PlayBASIC Code: [Select]
  ;        If Ys < 0 Then Ys = 0 
; If Ys > Y_Screen_Res Then Ys = Y_Screen_Res

Ys = ClipRange(ys,0,Y_Screen_Res)








ScottieB

#20
Thanks again for the help I'll work on it.

Any Ideas how we can get bi-linearal filtering like you have in images or do we have to implement somthing?

And the big question! ...

How do we add grasss or trees efficiantly?  3D-Sprite Scaling?  3D data used for sprite scaling or is there a better way or faster way???

Also Clouds / Sky? any ideas?  Not sure how to approach making the project bigger? Some kind of structure on how to expand would be great!!!!

Upon further reading the altitudes can be filtered and the textures can be filtered for better output looks.



Thanks!
ScottieB

kevin

#21
 To apply a bilinear filter you'd need 4 colours.     You then interpolate the 4 colours..

  (0) LEFT RGB -  (1) RIGHT RGB
  (2) LEFT RGB -  (3) RIGHT RGB


For the vertical strips, you'd interpolte the R.G,Bs from the last colour to the next colour..

   // compute difference between  the R channels
   DR#= RGBR(OLD_COLOUR) -RGBR(NEXT_COLOUR)

do the same for GREEN and BLUE channels


 Then divide the Height difference into the colour differences

 So you compute change in colour over time (time being pixels in this case)

     RSTEP#   =  DR#  /  float( OLD_Y-NEW_Y)


 then the inner loop is basically


PlayBASIC Code: [Select]
  CurrentR#=  RgbR(OLD_COLOUR)
CurrentG#= RgbG(OLD_COLOUR)
CurrentB#= RgbB(OLD_COLOUR)

For CurrentY = OLD_Y to (NEW_Y-1)

Dot Xpos,CurrentY, RGB(CurrentR#,CurrentG#,CurrentB# )

CurrentR#+= RSTEP#
CurrentG#+= GSTEP#
CurrentB#+= BSTEP#
next





 That's about it....  Although the GouruadStripV commands would be faster than such a loop.  


 Sprites:

     For sprites,  you'd need to write a Z buffer.   So when you plot the pixels in the sprites, you compare the pixels Z depth with the display depth and only write if the Z is lower.    So there's a lot of extra memory access with a zbuffer.   But you could interleate the 'screen an dzbuffer into one buffer. So when you read/write the CPU is pulling data close to each other.  
   
      You could do it without a zbuffer, by clipping the terrrain vertical spans to the vertical spans of the sprites.  There's probably a few gotcha's in doing  both,  there always is..



kevin