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
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
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
Thank you! I'll check it out and get back to you as I move forward!
Bye for now,
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
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..
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.
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.
Here's a slightly tweaked version of the second version
[pbcode]
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
[/pbcode]
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
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
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
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
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.
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,
ok kev, i understand how mod works in C libraries now.
the point i was making, as i misunderstood, was between code & windows 10 calculator:
computer calculator:
8 mod 512 = 8
-8 mod 512 = 504
pb code:
8 mod 512 = 8
-8 mod 512 = -8
the negative value on the windows calculator wraps neg numbers between 0 - 512 as the boundary. so the windows calculator acts like the wrap command.
i understand the difference now, i will use the wrap command instead.
thanks kev
hey scott
i fixed the texture flipping issue, yay (see pic). compare this pic with the one in reply #11.
did you want the textures to face the same way too? depending on the angle, they can be upright or upside down... or just leave as is.
now i can refine my TextureStripH method. i will post when done.
stevmjon
Can't wait to check it out! I guess I would like the textures just to be right when I put image of say a race track on them it's the only logical thing I can think of.
Sorry, for the code errors but the tutorials I worked with did'nt seem to work this out right like where trying to do. So thanks for trying Steve O'
Scott_Bro
is the goal one of these methods:
1 > goal is like placing the image on the ground (but image is tiled) and player can move around like being on it?
2 > goal using an image and have it scroll down screen like a car driving (like pole position demo)?
i am actually having fun with this, so i will edit code again to make method 1. i am interested to see if i can do it, with image tiled on the ground, and it will have texturestriph draw method.
also, i assume the image is planned to be drawn on the bottom half of the screen only?
stevmjon
I was thinking like a mariokart of f-zero racetrack bottom only but it still makes a nice demo if you work out correct textexed tileing!
PlayBASIC Racer Tech Demo (https://www.underwaredesign.com/forums/index.php?topic=1534.0)
cool demo kev.
even after all these years in playbasic, i still seem to see programs for the first time. and that one was made back in 2006.
Here's the WIP thread about PB Racer (https://www.underwaredesign.com/forums/index.php?topic=1472.0) which has a bunch of progression screen shots.
Yeah it's pretty old alright.. I was thinking it was about 2010 ish, but it was posted in 2006. Scary
well scott
i finally got the demo for the image tiled on the ground. took longer than i thought. i left all the commented lines in so you can see i experimented a lot, that is why i took so long, lol.
this runs at 75 fps on my rig (lockbuffer = off). it was faster earlier, but as the image gets so small for the distance, the command texturestriph repeats a lot on those ray lines. it is still faster anyway.
i wanted to see if i could figure it out, before looking at kevs demo he posted. he has it done very well.
had fun doing this, hope it helps, stevmjon
edit: see edit 4 in post below (reply #27). it is a cleaned up version.
Very cool ! and a bit of scary nightmare to pick through the source code..
I guess you could try making a 3*3 array of the texture which would keep more of the UV's inside clip zone, but then you offset that against the bigger chunk of memory that needs to read.
yeah, i left the code all in comments to show how much experimenting i needed to do, lol.
good idea with the texture. i didn't know that was a good idea actually. i thought the smaller the texture the faster it was read?
but i guess in this demo, making it bigger would help texturestriph.
Quotegood idea with the texture. i didn't know that was a good idea actually. i thought the smaller the texture the faster it was read?
but i guess in this demo, making it bigger would help texturestriph.
Reading from a big interval between pixels in memory is indeed slow. So making it too big will choke on systems with slower memory due to the data cache constantly being forced to read / flush chunks as they go in and out of scope. The question is is the Vm cost more or less than the reading penalty ? I've NO IDEA :)
You could store the ground / roof textures in 16bits and or use a palette mapped 16bit. Which halves the memory foot print and providing the source texture has less than 2^16 colours in it, would produce the same visuals. This is how first generation consoles and early software rendering solutions on the PC worked.
or we could add masks to wrap the UV's with the source texture.
hey scott
edit4 is a cleaned up version, compared to edit3. i also forgot to re-enable "lockbuffer", so this now runs even faster, at 300 fps on my rig (yay).
i also added move forwards / backwards too.
i left the border checks seperate to each other for easy reading/edit. so there is a right edge, left edge, top edge and bottom edge checking for the wrapping of the image texture.
have fun, stevmjon
PlayBASIC - Code Snippet Mode7 cart racing demo by Stevmjon & Scott_Bro - (2021-11-02)
This video features Steve's 4th edit of the Mode7 demo that he and Scotty Bro have been working on in recent weeks. You can find this and other various PlayBASIC source codes in the series on our forums.
Steve,
You (or we if you like) should wrap this stuff up into a little library to make mario kart style games. would just need something to compute sprites and that's about it.
scott does have a 'pole position' demo that already has cornering in it.
do you mean add a racetrack image and drive on this? yeah that should work.
i assume if people used this, they will need to manually set where the road actually is for sprites to drive on it, when using their own maps?
Thanks for all the help steve but can you tell me if this is easier to mod?
I kinda looks the same just need a little work. Would you call it the same? sort of? or am I really off.
cool scott, this works fast. i am always impressed at how well you minimise code.
this works fine. just a different way of going about it.
keep up the good work.
quads are the easy way and the only difference will be the perspective.