Taylorza & Wouter Help Please :)

Hey you RLP masters, I would absolutely love to do some really minor 3D work on the Hydra and I could use some help.

I don’t even know where the Hydra’s LCD memory starts; I tried looking at the chip docs, but I really never deal with stuff this low level.

If I could get the memory start and Chris’ 3D stuff that would be amazing.

One little thing that I’d like to do is allow GameSlate users to have avatars like on the XBOX but instead of high detail slick renders I was thinking a MineCraft style block avatar with basic tile skins for customization.

Thanks in advance guys!!!

@ Skewworks - I have not (yet) moved the ray-casting engine over to the Hydra, It was done on the Spider, however I definitely plan to migrate it and plan to release the full code. I will also need to make what ever adjustments are required to make it work with RLP Lite, I have not looked at RLP Lite at all yet, I have seen comments that the argument Marshalling might be a pain and I marshal all the data on initialization to the engine from managed code ie. the map design and the textures etc.

I am sure you found this already, but just in case, here is the documentation on the LCD controller for the AT91SAM9 processor range
http://www.atmel.com/Images/doc6300.pdf

I have not gone through all of this yet, but I hope this will be the right starting point. I will try get a RLP Lite build environment setup for the Hydra this week.

@ Skewworks - I quickly checked the Hydra firmware code and the LCD base address is set to 0x20F00000. Using RLP you should read this out of the LCDC Registers (AT91C_LCDC_BA1 : 0x00500000) rather than hard code it. Here is a quick managed code implementation of a SetPixel function I put together to confirm the address using the AddressSpace class.


const uint BaseAddress = 0x20F00000;
const uint Stride = 320 * sizeof(short);
byte[] _pixelBuffer = new byte[2];

public void SetPixel(int x, int y, Color color)    
{
  uint offset = (uint)((y * Stride) + (x << 1));
      
  byte r = (byte)(ColorUtility.GetRValue(color) >> 3);
  byte g = (byte)(ColorUtility.GetGValue(color) >> 2);
  byte b = (byte)(ColorUtility.GetBValue(color) >> 3);
      
  short pixel = (short)((r << 11) | (g << 5) | b);
      
  _pixelBuffer[0] = (byte)(pixel & 0xff);
  _pixelBuffer[1] = (byte)(pixel >> 8);      

  AddressSpace.Write(BaseAddress + offset, _pixelBuffer, 0, 2);
}

2 Likes

You shouldn’t fix your code to a specific address. What if we moved it in future?

The base address is stored in the LCD register (can’t remember the name of it) so you should read that for the address.

Like

Register LCDBASE = new Register(0x12345678 see datasheet);
uint baseaddress = LCDBASE.Read();

@ Gus - I agree, which is why I included the following statement in my reply

0x00500000 is the Register that should be read to get the address.

@ taylorza - My hat off to you :slight_smile: I didn’t read the post, only saw the code, well done.

Thanks guys you’re awesome!

I’m very new to this kind of coding so I’m sure I’ll have lots of follow-up questions, but I was new to c# (came from a VB background) when I made Pyxis 2 and now C#'s my default language at the dayjob. :slight_smile:

Sorry for my absence, but I see taylorza already answered the question :slight_smile:

So I’ve got some basic 3D stuff working, but even in RLP it’s pretty slow.

I know the issue lies in how I’m painting to the screen; if I just did a flat RLP pixel by pixel fill to screen it takes > 1 second. I assume you’re both using some nice assembly tricks to draw faster.

Let me give you a little better idea of what I’m trying to achieve and what I’ll do with it.

In the most ideal world I’d like to setup a Viewport to render (i.e. a specific portion of the screen); failing that I can render full screen and just have it paint some other stuff behind. Next basic 3D object rendering, and boy do I mean basic. We’re talking ~100 polygons for the most complex object I’d be rendering. Finally I’d like to put a single layer not bumped texture on it.

I can manage all of the 3D maths and talking from managed to RLP but man is this painting to screen stuff killing me.

Everything is being created for GameSlate, which is FREE. And I’d absolutely love some help. I know some stuff you guys have put a lot of work in to and aren’t eager to just give it away. So there are a couple of things I could do. I can close the RLP source and credit you, keep it open, or possibly even pay. To be honest I don’t really see GameSlate ever bringing in a lot of money, but I do really want to get it out there so I’d be willing to throw my own money at it. :slight_smile:

@ Skewworks - I have no issue sharing the code I have, I just have not had a chance to convert it from RLP to RLP Lite and clean it up a little so that I do not embarrass myself too much, I was having too much fun playing with my custom build of the Hydra firmware :slight_smile:

Are you saying that filling the screen with something like the following C code (native not managed)


for (int x = 0; x < 320; ++x)
{
  for (int y = 0; y < 240; ++y)
  {
    setPixel(x, y);
  }
}

Where setPixel() is just a function which writes to the memory buffer, takes more than 1 second? If so, that seems strange, I have not tried this with the Hydra and RLP Lite, but with RLP on the Spider the above would be very quick, my raycasting engine does this and much more for each and every frame and as you saw on the videos I am getting a pretty good frame rate and would expect even better on the Hydra.

If you post some code I will gladly take a look and see if I can see something that might be an issue in terms of performance.

Yeah doing that native takes about a second. Using the managed version you supplied is >4 seconds. That’s what stalled my 3D development before was drawing to screen in RLP. I had come across an example long ago that wrote to a byte array that was converted to a BMP an then rendered; also took way too long.

For the 100polygon object it’s to make a very basic (think mine craft) avatar for the user. Most 3D would be closer to Starfox low poly count and very little texturing.

Right now all my 3D stuff is in managed. I figured I could start there and work on porting once I understood the native drawing better.

I plan on doing a simple Viewport with rotating cube in several render modes tonight in managed C#. Perhaps I could email you a link to the source at the end of the night and see what you can manage in RLPlite? All help is greatly appreciated and I’ll be more than happy to plaster you name all over :slight_smile:

GameSlate’s had a massive facelift since I last demoed it…can’t wait to show off new stuff (hopefully w a 3D avatar)

The managed code I understand, but the native code, that is very surprising. When I first got the Spider I did some spinning cubes in managed code and quickly concluded that managed code and 3d will not work. I doubt that even with a Hydra will a basic voxel engine will be doable with managed code, and that is assuming only filled polygons never mind texture mapping them.

Please send the code, just keep in mind that we have a time-zone difference so I will probably not respond immediately. It is time for bed here.

I will be in the States next week which will put me out of play for about 2 weeks. So I will do my best to look at it during this week.

@ Skewworks - Sorry I forgot, you can send me the link to


string name = "chris";
string domain = "dotnetwarrior";
string tld = "com"
string email = name + "@ " + domain + "." + tld;

2 Likes

now that’s how to get around spambots :wink:

So it’s only wireframe at the moment but I’ve got it running at over 30 FPS in managed with 60 polygons multiple colors and no optimizations :slight_smile:

That’s enough for the most basic 3d games of all time (like battlezone). In fact, I think I’ll start with something like that and then move on to flat fills followed by textures.

Lots left on just the wireframe engine but a couple of weeks and I should have something. Would be a few days but too much real world work to do.

I finally got a gap to setup a GCC RLP environment for the Hydra and I did a quick test filling the screen with a solid color, I wrote 2 functions one that takes advantage of the fact that I am filling the entire screen, but not using any of the standard library functions (they would be even better) the second is a naive pixel by pixel fill screen.

I executed each function 60 times from managed code with the following results
RLP_FillScreen : 474ms
RLP_FillscreenSlow : 1693

That is
RLP_FillScreen => 126.5 Frames per second
RLP_FillScreenSlow => 35.4 Frames per second

Here is the code

Native:


 #define LCD_BASE_REG          0x00500000
 #define LCD_BUFFER_ADDR       (*(unsigned long *)LCD_BASE_REG)
 #define LCD_BUFFER            ((short*)LCD_BUFFER_ADDR)

void setPixel(int x, int y, short color);

int RLP_FillScreen(int *par0, int *par1, unsigned char *par2)
{	
  short *pBuffer = LCD_BUFFER;
  short color = *par0;
  
  for (int i = 0; i < 320 * 240; i++)
  {
    *pBuffer++ = color;	  
  }
  
  return 0;
}

int RLP_FillScreenSlow(int *par0, int *par1, unsigned char *par2)
{	
  short color = *par0;
  for (int x = 0; x < 320; x++)
  {
    for (int y = 0; y < 240; y++)
    {
      setPixel(x, y, color);
    }
  }
  
  return 0;
}

void setPixel(int x, int y, short color)
{
  long offset = (y * 320) + x;
  *(LCD_BUFFER + offset) = color;
}

And on the managed side I have the following


using System;
using Microsoft.SPOT;
using GHI.OSHW.Native;
using GHI.OSHW.Hardware.LowLevel;

namespace MFConsoleApplication1
{
  public class Program
  {
    public static void Main()
    {      
      byte[] binFile = Resources.GetBytes(Resources.BinaryResources.RLP1);
      AddressSpace.Write(0xa0000000, binFile, 0, binFile.Length);

      RLPLite.Procedure RLP_FillScreen = new RLPLite.Procedure(0xa0000000);
      RLPLite.Procedure RLP_FillScreenSlow = new RLPLite.Procedure(0xa000008c);

      int[] color = {255};
      int[] emptyInt32Array = { };
      byte[] emptyByteArray = { };

      DateTime dtStart = DateTime.Now;
      for (int i = 0; i < 60; i++)
      {
        int ret = RLP_FillScreen.Invoke(color, emptyInt32Array, emptyByteArray);
      }
      DateTime dtEnd = DateTime.Now;
      Debug.Print((((dtEnd - dtStart).Ticks) / TimeSpan.TicksPerMillisecond).ToString());


      dtStart = DateTime.Now;
      for (int i = 0; i < 60; i++)
      {
        int ret = RLP_FillScreenSlow.Invoke(color, emptyInt32Array, emptyByteArray);
      }
      dtEnd = DateTime.Now;
      Debug.Print((((dtEnd - dtStart).Ticks) / TimeSpan.TicksPerMillisecond).ToString());
    }
  }
}

1 Like

Thanks Chris

With Wouter’s 3D going so well on RLP and the 3 of us working on things I think maybe we should find a time to do a chat or something. Roadmap the engine and divide the work. I know there’s big timezone issues so maybe very early or late on Saturday might work?

Skewwerks, I’m waiting to send you a invitation to the code on bitbucket because I want to figure out how to dynamically allocate memory for a 3D Object (an object contains multiple faces and defines one color) and Faces (which are triangles) in RLPLite. malloc and new fail hard, so I’m thinking of working with a pre-defined array or something. Any other ideas?

I want to have a clean start for everyone to jump in.

No ideas on the RLP side. I’m very surprised to see mem_alloc not working.

From my side I’d have a managed engine that had predefined meshes (with faces and properly ordered polygons) in a “scene” which I could manage to only change per level if there were a visibility flag.

I know the byte arrays passed in are pointers so maybe if managed side housed all the meshes and passed them in a compatible format then managed could take care of the array sizing and memory allocation?

@ WouterH - Are you using GCC? From what I understand we will need to implement the stubs for newlib that manage the memory allocation. We probably need to implement them to allocate memory from the RLP reserved memory. Unfortunately I am traveling to the US this weekend and will not be around for the next 2 weeks and will not have a chance to look into this.

@ Skewworks, I am game to implement a 3d engine, this stuff is always fun. Did you get to try the code I posted, I am interested as to why you had such a low performance with the RLP.