News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Mode 7 - Part One

Started by Scott_Bro, October 17, 2021, 02:55:13 PM

Previous topic - Next topic

Scott_Bro

Here's a little demo I through together today trying to understand mode 7.

Can someone show me how to buffer our textures and read from them because it's screwing up the rendered output.

I though that would be a great place to start for now.

Thanks,
Scott_Bro

stevmjon

#1
i assume you want to read from the image to get point data, while the screen is locked with lockbuffer?

well, you could point to the memory address of the image itself, then offset from there to read point data...
not sure it won't break lockbuffer though. or try texture strip? might be faster, if you can read from the image itself.


another way is to just place all the pixel data in an array, then access that array data in the correct location. you could make one element array and read by offset by image width, like line number. or just make a 2 element array with width,height element values.

is mode 7 where you draw 1 line at a time and offset each line by z divide?

   stevmjon
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

stevmjon

#2
hey scott

here is a quick demo with a 2D array to store the image pixel data into.

at least it will give you a basic idea on how to go about this one way.

hope it helps, stevmjon
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

Scott_Bro

Thank you! I'll check it out and get back to you as I move forward!

Bye for now,
Scott_Bro

Scott_Bro

Yo! Steve,

Have a look at an updated version.  It's still rather slow though.  Try moving the arrow keys left & right and you'll see I added rotation today.  Unclear to why? texture map is flipping around here and there.
Try tinkering with the code and see if you can come up with the reason why?  Still, I'm working on it myself but you might figure it out before me.  I'm rotating 10 degrees at a time and you see what I mean about speed.
It's kinda slow but it is now at full texel level detail.

Any help and I would be greateful!

Thanks again and as always happy computing.

Scott_Bro

kevin

#5
   Made a video on this last night


 



  One hint for your newer version pre-compute Cos & Sine(Theta) from the inner loop..   They are pretty expensive functions..

stevmjon

i am in the middle of looking at the code now, and for a test i changed reading an array to using texturestriph. this routine is almost done, and the fps = 230. i just need to refine it a bit more.

i will look at the textures next, just thought i will let you know about texturestriph.

kev posted before i finished this one. got a warning message. will watch the video.
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

stevmjon

#7
i worked out the image thing. an example is when you are reading the image uv coordinates from top to bottom, draws the upper half correctly, then you then draw the lower half from bottom of the image to top, so upside down there. when you rotate the whole process reverses. so sometimes the lower half of screen is correct, sometimes the upper half is correct, but not both at the same time. you need to match the upper half and lower half to read the image the same direction. also your rotate value changes direction too. so at zero degrees it one direction, and 90 degrees its another direction. cos & sin values reverse every 90 degrees. i will try and figure out a fix, unless you come up with one first.
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

kevin

 
Here's a slightly tweaked version of the second version

PlayBASIC Code: [Select]
X_Screen_Res = 800
Y_Screen_Res = 600

Color_Mode = 32
Windowed_Mode = 1

OpenScreen X_Screen_Res,Y_Screen_Res,Color_Mode,Windowed_Mode

TitleScreen "Mode 7 - Part Two"

LoadFXImage "textures\test_texture_2.jpg",1

RenderToImage 1

LockBuffer

Seed = Point(0,0)

Width = GetImageWidth(1)
Height = GetImageHeight(1)

Dim Texture_Map(Width,Height)

For Y_Texel = 0 To Height - 1
For X_Texel = 0 To Width - 1

Texture_Map(X_Texel,Y_Texel) = Point(X_Texel,Y_Texel)

Next X_Texel
Next Y_Texel

UnLockBuffer

RenderToScreen

X_Cntr = X_Screen_Res / 2
Y_Cntr = Y_Screen_Res / 2

ScaleX = 32
ScaleY = 32

Do

Cls

LockBuffer

Seed = Point(0,0)

Z = Y_Cntr * -1

cos_theta#=Cos(Theta)
sin_theta#=sin(Theta)

YB=Y_Screen_Res-1
For Y = 0 To (Y_Screen_Res/2) - 1

/*
New_Y# = Float(Y) / Z

If New_Y# < 0 Then New_Y# = New_Y# * -1

New_Y# = New_Y# * ScaleY

New_Y# = Mod(New_Y#,Height)
*/


For X = 0 To X_Screen_Res - 1

Cx=(X_Screen_Res - X)
New_Y# = Cx * Cos_Theta# - X * Sin_Theta#
New_X# = Cx * Sin_Theta# + X * Cos_Theta#

New_Y# = New_Y# / Z
New_X# = New_X# / Z

If New_Y# < 0 Then New_Y# = New_Y# * -1
If New_X# < 0 Then New_X# = New_X# * -1

New_Y# = New_Y# * ScaleY
New_X# = New_X# * ScaleX

New_X# = Mod(New_X#,Width)
New_Y# = Mod(New_Y#,Height)

Color = Texture_Map(New_X#,New_Y#)

FastDot X,Y,Color
FastDot X,YB,Color

Next X

Z = Z + 1
YB--
Next Y

UnLockBuffer
text 20,20,width
text 20,40,height

Sync

If Leftkey() = 1 Then Theta = Theta - 10
If Rightkey() = 1 Then Theta = Theta + 10

Theta = Mod(Theta,360)



Loop spacekey()

End


stevmjon

#9
gettin faster kev.

oh, scott
i made a test demo of the uv image being sampled and to see this drawn to screen line by line. the dots on the image are drawn to x = 0 screen coordinates.
this is the texturestriph version half complete. it follows the same sample line as part 2.

i thought this will help you see the difference at different angles and the upper/lower half. rotation is disabled and it auto rotates 90 degrees for you to watch.

  hope this help, stevmjon
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

Scott_Bro

Holy moly!

Weirdness, about that flip/floppy thingy.  Thanks for point it out. I'm watching your video and man there are many ways of attacking that one I see.
But what about 230fps what the heck! I love to see that one plus mine is still bogging out so that version would be great to see especially if you work out flip/flop too.
I'm kinda busy today but I look back later to see if there are any updates kevin sped up the rotation some as well. kewl! 

Talk soon I hope.

Thanks again steve for the help!

Scott_Bro

stevmjon

#11
i worked out the flip flop thing. if you go out of the image range coordinates, you are turning the value around, instead of wrapping it.
you are dividing by -z, which works for values inside the image, then you invert sign to make pos. this is a problem for outside ranges of the image. it 're-bounds' instead of wrapping.
it seems to effect -y and -x outside image (which get /-z so change to pos). they get re-bounded.

i experimented on making a visual demo (see pic). here i have every 5th line being drawn how you would see it taking samples from the image (i did let the x go outside though). focus on the lines going up then re-bounding (should wrap).

i will see if i can work out a fix. see these below:

Z = Y_Cntr * -1  ;  divide is a neg value

New_Y# = New_Y# / Z    ;    neg y value(outside image) gets turned into pos value
New_X# = New_X# / Z

If New_Y# < 0 Then New_Y# = New_Y# * -1    ;    since outside y is now pos, it skips this step
If New_X# < 0 Then New_X# = New_X# * -1

New_X1# = Mod(New_X#,Width)
New_Y1# = Mod(New_Y#,Height)    ;    y that is pos won't wrap ***

need to change above behaviour, to allow wrap.

  hope this helps, stevmjon
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

stevmjon

erm... uncle kev...

thought i will post here to ask this question, because i was trying to use it in scott's part two demo and couldn't figure out why it wasn't working.

* does command  Mod(number, divisor)  allow neg values for the number??

the reason i ask is i tried this on a calculator and it works as expected. if the 'number' is negative it wraps.
playbasic keeps a neg value as a neg value (won't wrap).
thought i wiould ask in case it's a bug. else i can use another command or manually calc this.

   stevmjon
It's easy to start a program, but harder to finish it...

I think that means i am getting old and get side tracked too easy.

kevin


Steve,

     Most if not all the common math functions in PB are basically wrappers of C/C++ math library functions, will have a look after anyways.   

kevin


Steve,


    The existing function matches the C libraries..   Although I do have some memory that it may have been positive only as some point in the past, but who knows when that was.. 




  Example

for lp=-10 to 10
s$=s$+ str$( MOD(lp,4))+","
next
#print s$: s$=""


for lp=-10 to 10
s$=s$+ str$( MODI(lp,4))+","
next
#print s$: s$=""

for lp=-10 to 10
s$=s$+ str$( MODF(lp,4))+","
next
#print s$: s$=""


  spits out;

-2,-1,0,-3,-2,-1,0,-3,-2,-1,0,1,2,3,0,1,2,3,0,1,2,
-2,-1,0,-3,-2,-1,0,-3,-2,-1,0,1,2,3,0,1,2,3,0,1,2,
-2.0,-1.0,0.0,-3.0,-2.0,-1.0,0.0,-3.0,-2.0,-1.0,0.0,1.0,2.0,3.0,0.0,1.0,2.0,3.0,0.0,1.0,2.0,