-=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- (c) WidthPadding Industries 1987 0|490|0 -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=- -=+=-
SoCoder -> Snippet Home -> Graphical Engines


 
mike_g
Created : 12 August 2007
 
Language : Blitz

Raycaster



Heres a raycaster I'm working on. It has some clipping problems at the moment, and could be made faster, which are things I'm working on.

And heres the texture needed:

 

Comments


Sunday, 12 August 2007, 07:19
Jayenkai
Seems to work well enough, if a little slow, but then that's Blitz's pixel drawing for you!

I've never attempted to do anything like that, myself. Can't wrap my head around all the maths.. I think I'm overthinking it all!
Sunday, 12 August 2007, 07:43
mike_g
Yeah the maths is pretty hardcore. I made this working off a C++ tutorial, and I'd say I half understand it. Still I'm hoping to learn it better, by adding features like multiple height and diagonal walls. Its useful stuff to know.
Sunday, 12 August 2007, 08:23
power mousey
Kudos for you. True.
good work, mike.

Thank you for this program. I will definitely learn
from you concerning this. Yet, right now I'm caught more
into animation sequences and scenarios.
One of these days...I'll be Half Life on the Quake
and Halo on the Doom.

cheers,
power mousey
Sunday, 12 August 2007, 08:35
shroom_monk
Wohoho! I have to hand it to you, Mike! You achieved what I attempted to do with my failed 3D program! I just couldn't get the maths to work. I have to take a look into this...

Very well done!
Sunday, 12 August 2007, 09:05
Phoenix
That looks quite complicated! It doesn't run slow here, it's way too fast; I barely have any control over the camera cause it's so fast On a laptop!
Sunday, 12 August 2007, 12:00
mike_g
Thanks guys

@shroom_monk: I'm not all that clever really, I coded the raycaster working of this tutorial, which explains how it works quite well if youre interested.

I just made a level editor for it. You can download the raycaster with level editorhere. Theres a test level I made called (surprise) "Test" with it too.

I'm hoping that I'll be able to turn this into a doom-like game engine of some sort, but theres still a hell of a lot of work to do if I'm going to get that done.
Sunday, 12 August 2007, 13:38
shroom_monk
I haven't taken much of a look at the tutorial (I will read it properly later), but I assume this works by simply resizing those images somewhat? If so, I'm now kicking myself. I was trying to calculate the position of every pixel...
Sunday, 12 August 2007, 14:28
power mousey
hey mike and hey Shroomie
and also everybody else here too

I found this link about Raycasting.
It looks interesting. I will read about it later
cause I'm off to sheepland for more sleep.

again, thank you for sharing with me mike
and also for teaching me something too.

here is the link:

en.wikipedia.org/wiki/Ray_casting


cheers to you both
power mousey
Sunday, 12 August 2007, 14:56
mike_g
@ powermousey: Raycasting is basically fake 3d. You dont need Blitz 3D to run this.
Wednesday, 15 August 2007, 07:57
power mousey
thank you, mike g.



kudos true,
power mousey
Wednesday, 22 August 2007, 14:20
ingenium1
5 FPS here :\
Wednesday, 22 August 2007, 17:22
mike_g
Wow, thats slow. Doubt even shoom monk gets that low fps. Best thing to do is change GRAPHICS_WIDTH and GRAPHICS_HEIGHT to something like 400 * 300. That should run a lot faster. It could be down to your computer not liking all the WritePixelFast operations, theres 640*480 of em and blitz seriously sucks at pixel writing.
Wednesday, 22 August 2007, 18:14
Nolan
Pretty neat. ~30 fps here.
Wednesday, 22 August 2007, 19:32
JL235
I got about 6 too, and then I turned debug off and got almost 30. I'd expect that is what was slowing it down for Ingenium.

But I remember seeing that tutorial years ago. Someone linked to it from BlitzBasic.com. I really wanted to make a Doom style game but found it difficult at the time to follow the tutorial whilst having to write it in Blitz. I might try again in Java, so expect to see some competition.
Wednesday, 22 August 2007, 19:52
mike_g
Haha. Cool. A java version could possibly be better. I rewrote this checking the rays at regular intervals instead of using DDA. It makes it even slower, but fixes that annoying clipping bug. I swear I did a straight conversion, which leaves me thinking that either there was something wrong with the original code, or the fact that theres no 'double' floats in Blitz which was causing problems.

I'll post an update soon. I should have the sprites sorted out too.
Thursday, 23 August 2007, 19:40
Mog
This is a good example of a High-Def Raycaster. I Just hate that blitz is so damned slow that your average users can't really run stuff amazingly fast. I only got 50fps on my main computer.
Friday, 24 August 2007, 07:39
mike_g
Yeah, Blitz pixel writing sux :/ One thing you could do to get the framerate up would be to set Flip to False. I imagine that should at least bring it up to at least 60fps for you.
Sunday, 26 August 2007, 11:46
JL235
I made a few changes to your code too, trying to make it faster. I'm pre-drawing the sky as an image (which also means I can remove that section of the rendering) and I've removed the screen array. Now it's drawing directly to the backbuffer. I also added a 'precalculatedHeights' variable before the nested y for loop, which just pre-calculates the hight you subtract from 'y' to get 'd'.

I was also going to implement another improvement where it will calculate how big the texture is in relation to where you are drawing. Essentially if the texture is only 64 pixels high, but your right up close so it appears to be 480 pixels high, many of 'tex_y' calculations can be skipped because they will give the same result. To draw I was going to use the line command (which works on a locked buffer) to draw in from the previous pixel position to the next.

However Blitz doesn't allow you to step by a variable, it must step by a constant value. So I can't do this. I did do it in my Java version where I did find a speed increase.


Sunday, 26 August 2007, 13:08
mike_g
Cheers diablo I'm coding a demo at the moment, but when I get back to this I'll check out the changes you made.

I was also going to implement another improvement where it will calculate how big the texture is in relation to where you are drawing. Essentially if the texture is only 64 pixels high, but your right up close so it appears to be 480 pixels high, many of 'tex_y' calculations can be skipped because they will give the same result. To draw I was going to use the line command (which works on a locked buffer) to draw in from the previous pixel position to the next.

I like the sound of this. I might see if I can do something similar

I have actually got a newer version of this prog. I had added lookup tables for the heights as well as sin/cos tables, and a few other things. Those speed increases have been lost tho because I had to change the code to check the rays at regular intervals instead of using DDA in order to fix that hideous clipping problem So the new versions actually quite a bit slower.

As to do with the screen array, there is a reason for it. I have noticed that Blitz writepixel works much faster when performed on consecutive memory locations, as opposed to jumping between various areas of the screen. Also reading/writing to an array is much faster than to an image buffer. As I plan to add sprites to this, it would be faster to draw everything to an array then blit it to the screen in one go. Drawing the sky to an image is also nice, but again I was planning on adding features to it like clouds and stuff.

Anyway heres the latest version I got. It has a few extra features, such as lighting effects for indoor sections. And now I have a bug with the floorcasting, but its not as bad as the clipping one.

Download Link
Sunday, 26 August 2007, 13:25
steve_ancell
Very good result. I'm getting between 35 and 50 FPS over here.
Sunday, 26 August 2007, 13:41
mike_g
I think I might recode this in C. I know its ironic, but the speed in Blitz is just too damn slow; especially if I cant use DDA to check the points of the rays. Also if I can figure out how to use the MMX/3DNow registers I can draw 4 pixels at once. I imagine they should be accessible in Java too
Sunday, 26 August 2007, 14:03
JL235
Highly doubt it. I believe C++ doesn't give you access to the registers. But I'm thinking of re-writing my code in C++, or at least putting the raycasting calculations into a dll.

That improve I suggested above also works really well. However it does lower the quality of the rendering due to rounding errors. It is only slight, and only really noticeable when compared to the pixel-perfect original.
Sunday, 26 August 2007, 15:51
Jayenkai
Some cracking work going on, there.. Well done, Mike.. And Diablo, too!

Interesting to see the framerate shoot up if you disable the render.
I wonder, would it be possible to create a C++ DLL to take a memory bank containing the screen data, and use that to render the screen, instead of relying on Blitz to do it?
Sunday, 26 August 2007, 16:31
mike_g
Diablo: Hmm, maybe not. Guess it couldent hurt to learn a little ASM then

Jay: I think Paul was trying to do something like that a while back. As in create a DLL in C to use with Blitz for faster pixel drawing. Don't know how he got on with it tho.
Monday, 27 August 2007, 05:19
JL235
I'm still working on a few bugs, but I'm trying out a new idea I had before I went to bed last night. First both light and dark colours are stored together in the array positions. This is more important for me because when drawing I'm using a Color object for storing the pixel rather then an integer value. That gave a very minor increase in frame rate.

What has given a huge boost however is that I am also storing how many pixels follow that pixel with the same colour. So for example lets say that in the section of the texture I'm drawing there are 5 pixels in a vertical row which have the same color (such the outline of the bricks in your building wall texture). Currently I will draw this same colour 5 times for each pixel on the texture. By storing how many pixels follow with the same colour I can simply tell it draw all 5 pixels together and then skip to the 6th pixel.

It should also mean that if the vertical strip I'm drawing is all one colour, it'll be drawn with one draw command regardless of how big that section is (although this isn't fully working yet).

The results are mixed so far. Some textures when drawn look exactly the same with no speed increase. Others are vastly increased by as much as 2 to 4 times in speed, but have lost quality. The quality is probably due to rounding errors which is one thing I will be hoping to improve.