Jump to content
  • Advertisement
Sign in to follow this  
FFA702

The struggle with raycasting in C# intensifies, need help

This topic is 1382 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Fellow up with my last post, i'm currently trying to implement 2s sprites in my raycaster written in C# following Lodev tutorial. Unfortunately, i'm out of luck. I'm using native csharp class to keep it simple and the set pixel class is so slow it's unusable. I tried an alternative way drawing sprites and masking out part that should be obstructed by walls without any good results. Either it's completely unusable or way to slow. I want to be able to draw few dozens of sprites at the same time. Can anyone please help me ?

Share this post


Link to post
Share on other sites
Advertisement

From your previous post, it looks like you're using a WinForms project.  If that's still true, and you're using standard WinForms drawing, use Bitmap.LockBits to update the entire bitmap at once instead of using multiple SetPixel calls (see link).

 

http://msdn.microsoft.com/en-us/library/5ey6h79d(v=vs.110).aspx

 

NOTE:  You don't have to do both a read and a write.  You can raytrace to an array and then copy your array into the bitmap without copying the bitmap into your array first.

Edited by Nypyren

Share this post


Link to post
Share on other sites

Alright so far so good. Found this page explaining how to use LockBits pretty well http://bobpowell.net/lockingbits.aspx . Got the code to work and fill my bitmap with blue pixel but i am unfamiliar with pointers and bytes. How would i write a simple function analogous to the SetPixel method ? I am looking at something like this :

 

 public unsafe void SetPixelByte(BitmapData Data, int R, int G, int B, int A, int x, int y)
        {
 
        }
 
Where RGBA would be the color channel and x and y would be the location to write on. Thanks in advance and sorry for my lack of knowledge, never played around with pointers and bytes.

Share this post


Link to post
Share on other sites
Rather than having a function to set one pixel at a time, here is what I would do: I'd make a 2D array of uints to store the colors until I'm ready to put them all in the bitmap, then copy them over all at once.

(Let's say you started with a default WinForms example - use the following code in the Form1.cs file. Also make sure to enable "Allow unsafe code" in the Project properties' Build section)
 
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace BitmapSetExample
{
    public partial class Form1 : Form
    {
        Bitmap bmp;

        public Form1()
        {
            InitializeComponent();

            bmp = new Bitmap(256, 256, PixelFormat.Format32bppArgb);
            uint[,] pixels = new uint[256,256];

            for (uint y=0; y<256; ++y)
            for (uint x=0; x<256; ++x)
                pixels[x,y] = 0xFF000000 + (x ^ y);

            pixels[0,0] = 0xFFFF0000; // Use a red pixel to indicate where the 0,0 coordinate is (currently this example has 0,0 at the upper left)

            SetBitmap32bppArgb(bmp, pixels);
        }

        public static unsafe void SetBitmap32bppArgb(Bitmap bmp, uint[,] pixels)
        {
            int width  = Math.Min(bmp.Width, pixels.GetLength(0));
            int height = Math.Min(bmp.Height, pixels.GetLength(1));

            var bitmapData = bmp.LockBits(new Rectangle(0,0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            for (int y=0; y < height; ++y)
            {
                uint *row = (uint*)(bitmapData.Scan0.ToInt64() + y * bitmapData.Stride);
                    
                for (int x=0; x<width; ++x)
                    row[x] = pixels[x,y];
            }

            bmp.UnlockBits(bitmapData);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.DrawImageUnscaled(bmp, 0, 0);
        }
    }
}
Where pixels is a 2D array of uints, where each uint represents one pixel and has the hexadecimal layout: 0xAARRGGBB. Edited by Nypyren

Share this post


Link to post
Share on other sites
To combine separate red, green, blue, and alpha values into your uint, you could do something like this (this is specific to the layout that Format32bppArgb uses):
 
uint alpha = valueBetween0and255;
uint red   = valueBetween0and255;
uint green = valueBetween0and255;
uint blue  = valueBetween0and255;

uint pixelValue = (alpha << 24) | (red << 16) | (green << 8) | blue;
Edited by Nypyren

Share this post


Link to post
Share on other sites

Thank you alot for your help. While your solution looks appealing, i find it way easier for me to use function analogous to the native ones. Problem solved and thanks again you made my day, project was on hold last week because of this issue.

Share this post


Link to post
Share on other sites
Why write pixels with winforms?

You can do insanely fast 2d sprite drawing with OpenTK/OpenGL, and get cheap zooming, rotations, and cross-platform as well.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!