Jump to content
IGNORED

A 3d engine for the TI


Recommended Posts

 Howdy! This is gonna be a bit of an experiment for me. I'm going to be posting updates bit by bit as I put together a 3d polygonal engine for the TI that nobody asked for. 3D graphics on systems that don't support them has been a passion project of mine for quite some time. I've got a pretty complete engine put together for the GBA, and stubs for a whole bunch of other systems. But I've come up with enough improvements to my algorithms that it's about time to start from scratch, and well I've got that shiny new nanoPEB on my workbench... (at least one good thing came out of this pandemic). So I'm gonna be trying to post regular updates and demos here as I work through this.

 

 I've got plenty of experience with the math involved and assembly, but not with the tms9900 specifically. It'll be a little bit of a learning curve but hopefully it'll come out as something cool. So yeah, sit back, enjoy, and feel free to ask questions

 

Week 1

 So for this first week, I'm gonna lay out the general parameters of what I'm making. It's going to be a true 3d polygonal renderer, hopefully able to throw around graphics on something like the tier of starfox. It's gonna run at the full 256x192 resolution the TI can put out, and will have "semi" color graphics (still 1bpp, but with non overlapping objects able to have their own hue from the 16 color palette of the TI). With a bit of finagling, I think I can get some simple lighting effects and shadows running, but that's very much counting my chickens before the hatch. The target platform is a TI 99/4a with a PEB expansion, running from disk. There's a couple features on the TI that I think are going to make it a lot more suited to this sort of graphics than other 8 bit machines (namely a full 16 bit cpu, hardware multiplication and division, and the ability to shift the contents of a register based on the contents of another register (this one is actually the biggest, I'll explain what that means in a later post going over the specific algorithms I'm using))

 

In the meantime, enjoy a taste of that engine I made for the gba and Ramadan mubarak to whom it may concern

 

gbademo3.gif

  • Like 12
  • Thanks 1
Link to comment
Share on other sites

I would have thought that the only way to produce graphics like that would be to pre-render every object and load it from a large ROM cartridge. Are you planning to render directly to the VDP or to a RAM buffer first? I have some ideas for a linear screen buffer in CPU RAM and how to transfer it to the VDP, which I have never used. Indeed 16-bit multiplications are nice, but on the TI they are not signed. Or actually, if the result stays inside 16-bit they are signed (I think @mizapf made a proof for that a few (6-7) years ago). If you need any help with the TI stuff I would be more than happy to contribute.

Link to comment
Share on other sites

1 hour ago, AmericanSaracen said:

 I've got plenty of experience with the math involved and assembly, but not with the tms9900 specifically. It'll be a little bit of a learning curve but hopefully it'll come out as something cool.

The 9900 is pretty easy.  It has a nice orthogonal ISA and a lot of ALU capability compared to a lot of the 8-bit (and some 16-bit) CPUs of the era.  I think you will find the VDP part is going to be the biggest hurdle, and how to actually pump the amount of data you need to the VDP in a short enough time to make a playable game.  For sure lots of people will be watching with anticipation!

Link to comment
Share on other sites

I wish you luck! I'll be interested to see how you tackle the quirkiness of the TI. It may be one of the more "powerful" personal computers when it comes to instruction set capabilities, but as you'll also see the TI engineers tended to shoot themselves in the foot, the VDP being the prime example :P

Link to comment
Share on other sites

1 minute ago, matthew180 said:

@Gip-Gip That is true, however over the last few years we have seen the 9918A and 99/4A pushed to limits and doing things people previously thought were impossible.  There is nothing like a fresh perspective and positive problem-solving attitude when it comes to pushing hardware.

That's absolutely true, I'll be following this to see what comes out of it :-D

Link to comment
Share on other sites

Glad to see I whipped up a bit of excitement! I've got plans for sure. Basically what inspired this in particular is that I've found an algorithm to split up triangles into character based graphics very nicely (so every 8x8 region of a solid color is transferred as a character index rather than a bitmap). Hopefully that should cut down on the VDP bandwidth I need quite a bit. But yeah, I've gotta admit, the 99/4a is an odd duck. Weird architecture with some... interesting... decisions made down the line. But you've gotta love a misfit

  • Like 2
Link to comment
Share on other sites

That looks so cool, really impressive for GBA.  I'm fascinated by how you intend to do the polygon rendering into 8x8 character cells.  I can't wait for you to share more details about the specific algorithm you are going to use.

Link to comment
Share on other sites

 Day 2

 

 So, let's go over the basics of a polygon renderer -

So all 3d models are made of triangles. You do some funky matrix math on them (coming in a later session) to project their coordinates in the world-space into the screen space. From there, you have to determine which pixels are on the top somehow and get into the messy business of actually turning coordinates into pixels.

 

Now, taking a triangle made of x1,y1,x2,y2,x3 and y3, how can we actually determine which pixels are inside of it? The naive way is to check literally every pixel on screen - but this has some pretty obvious performance costs. Now, if our triangle had one edge that was perfectly horizontal, our job would be a lot simpler. We could just figure out the left edge and the right edge, and fill in a line between them.

 

Well, in the classical style of the engineer, to solve a difficult problem we just turn it into an easier problem and solve that. If we slice our triangle into two smaller triangles using a horizontal cut, they're now both the easy case to solve. We just iterate through each row, filling from the left edge to the right.

 

But we can do better still - this is where we're getting into the shaky math that i've come up with myself. In bitmap mode, no matter how you lay out your characters one byte on screen is going to be adjacent in ram to the one below it on screen rather than next to it. This obviously is gonna waste a lot of our time calculating all the addresses for each pixel on screen - so why not take advantage of it while we're at it?

 

First, we initialize every tile on screen to pattern 0 - this pattern is literally all zeros, will never display a color and will never be changed. But all other patterns are up for grabs - they're arranged in a nice little queue. Every time we try to draw a row of a triangle, we start with the left edge. We first check which pattern is currently there - is it a solid color pattern 0? if it is, we're going to grab a new pattern from the queue, copy 8 bytes of 0 into it since that's what was going to be displayed before, and write the new pattern we've set aside for it into it's place on the screen. Now, if it wasn't a solid color tile, we already know which pattern we're going to be rendering into. For each row of the pattern, it's simple to fill in using some bitshifts since the whole row fits in a register. If we were setting each bit to 1 as the color of this triangle, we'd calculate a mask with $FF>>(X&7). Then we'd just set NewByte = OldByte | mask for each row. And changing up the bitwise operations we can easily switch to setting each bit to 0 or some sort of dithered pattern for an intermediate shade.

 

Now, the right edge is pretty much the same thing, but what about the center? This is where I feel pretty pleased with myself. If we imagine for a second that the colors for each 8x8 tile are themselves a 32x24 bitmap, why couldn't we just do the exact same process on a triangle that's an 8th the scale of the first one? Except, instead of writing it pixel by pixel, we fill each space with pattern 1, which is just 8 rows of $FF. These still display solid blocks of the right color, but we don't have to write every transfer every single byte of them into the VDP. And if we ever tried to render part of a triangle onto one of them, we'd just turn it into a new pattern initialized with $FF on every row.

 

Now, obviously there's a million edge cases and minor optimizations to do, but that's the basic idea. For instance, it would probably be easier to use pairs of tiles as our patterns, since one row of a 16x8 tile would fit perfectly into our 16 bit registers, and then we could just rearrange it into two patterns when writing them into VDP ram (as I understand it, the VDP can't go quickly enough to do two writes one after the other, so a few SWPBs should take care of two birds with one stone). Hopefully all that made a bit of sense, and I'll be going over each part of it in more detail as we actually implement it.

 

Also, really dumb question, but how do I actually reserve a block of memory for variables? Right now I'm using the XDT cross development stuff since it seemed like the standard, but this really simple question has me a bit stumped

Edited by AmericanSaracen
  • Like 1
Link to comment
Share on other sites

It'll be interesting to see what you can come up with - but I think you should write some test code before you get too far ahead of yourself, to see if you can meet your performance goals.

 

Quote

Also, really dumb question, but how do I actually reserve a block of memory for variables? Right now I'm using the XDT cross development stuff since it seemed like the standard, but this really simple question has me a bit stumped

 

It depends on how you intend to use them, but if you literally just want a block, use "BSS" (block starting with symbol), and specify how many bytes big you want it to be. :)

 

MYVARS BSS 256

 

Quote

 (as I understand it, the VDP can't go quickly enough to do two writes one after the other, so a few SWPBs should take care of two birds with one stone)

 

You're fine doing two writes back to back on the TI, the multiplexer makes it nearly impossible to overrun the VDP. You DO need a delay after setting the address before the first read, though. But for everything else, the 9900 and the multiplexer seems to work out longer than the minimum delay needed, excluding some really, really niche cases).

 

One last edit: here's a thread where we went into detail on the VDP timing: 

 

 

Link to comment
Share on other sites

18 hours ago, PeteE said:

That looks so cool, really impressive for GBA.  I'm fascinated by how you intend to do the polygon rendering into 8x8 character cells.  I can't wait for you to share more details about the specific algorithm you are going to use.

This book from 1993 is all about 3D rendering with very lucid explanations and plenty of code examples. I used it to do the Fortran 99 3D wireframe demo having started knowing very little about the subject.

 

1476980488_FlightsofFantasy.thumb.jpg.cd45487d0c1895f3e704fd5e23237b96.jpg

  • Like 3
Link to comment
Share on other sites

13 hours ago, Vorticon said:

This book from 1993 is all about 3D rendering

I have that book too, bought it from the book store when it came out and it lives in the 3D section of my bookshelf.  I have read it a few times, but never put the information into code.  I think I was more interested in knowing *how* the 3D was done back then, rather than actually *doing* it. ;)  IIRC everything is there to implement a software polygon rendering engine, you only need to be able to plot pixels and lines.

Link to comment
Share on other sites

1 hour ago, matthew180 said:

I have that book too, bought it from the book store when it came out and it lives in the 3D section of my bookshelf.  I have read it a few times, but never put the information into code.  I think I was more interested in knowing *how* the 3D was done back then, rather than actually *doing* it. ;)  IIRC everything is there to implement a software polygon rendering engine, you only need to be able to plot pixels and lines.

I also bought it new back in the day and I finally decided to read it a month ago :) Really great book. And yes, all the algorithms for polygon rendering are there with code examples. 

 

  • Like 2
  • Haha 1
Link to comment
Share on other sites

  • 1 month later...
On 4/24/2020 at 8:38 PM, AmericanSaracen said:

 Howdy! This is gonna be a bit of an experiment for me. I'm going to be posting updates bit by bit as I put together a 3d polygonal engine for the TI that nobody asked for. 3D graphics on systems that don't support them has been a passion project of mine for quite some time. I've got a pretty complete engine put together for the GBA, and stubs for a whole bunch of other systems. But I've come up with enough improvements to my algorithms that it's about time to start from scratch, and well I've got that shiny new nanoPEB on my workbench... (at least one good thing came out of this pandemic). So I'm gonna be trying to post regular updates and demos here as I work through this.

 

 I've got plenty of experience with the math involved and assembly, but not with the tms9900 specifically. It'll be a little bit of a learning curve but hopefully it'll come out as something cool. So yeah, sit back, enjoy, and feel free to ask questions

 

Week 1

 So for this first week, I'm gonna lay out the general parameters of what I'm making. It's going to be a true 3d polygonal renderer, hopefully able to throw around graphics on something like the tier of starfox. It's gonna run at the full 256x192 resolution the TI can put out, and will have "semi" color graphics (still 1bpp, but with non overlapping objects able to have their own hue from the 16 color palette of the TI). With a bit of finagling, I think I can get some simple lighting effects and shadows running, but that's very much counting my chickens before the hatch. The target platform is a TI 99/4a with a PEB expansion, running from disk. There's a couple features on the TI that I think are going to make it a lot more suited to this sort of graphics than other 8 bit machines (namely a full 16 bit cpu, hardware multiplication and division, and the ability to shift the contents of a register based on the contents of another register (this one is actually the biggest, I'll explain what that means in a later post going over the specific algorithms I'm using))

 

In the meantime, enjoy a taste of that engine I made for the gba and Ramadan mubarakimageproxy.php?img=&key=f4dcc336a70d5c68imageproxy.php?img=&key=f4dcc336a70d5c68imageproxy.php?img=&key=f4dcc336a70d5c68imageproxy.php?img=&key=f4dcc336a70d5c68imageproxy.php?img=&key=f4dcc336a70d5c68imageproxy.php?img=&key=f4dcc336a70d5c68imageproxy.php?img=&key=f4dcc336a70d5c68imageproxy.php?img=&key=f4dcc336a70d5c68imageproxy.php?img=&key=f4dcc336a70d5c68 to whom it may concern

 

gbademo3.gif

Did you get anywhere with this?

  • Like 2
Link to comment
Share on other sites

On 4/26/2020 at 5:06 AM, Vorticon said:

This book from 1993 is all about 3D rendering with very lucid explanations and plenty of code examples. I used it to do the Fortran 99 3D wireframe demo having started knowing very little about the subject.

 

1476980488_FlightsofFantasy.thumb.jpg.cd45487d0c1895f3e704fd5e23237b96.jpg

I have this book, I dug it too.

  • Like 1
Link to comment
Share on other sites

I got a copy of that book too. I must have liked it, it survived the purge of "game related" programming books when I got rid of a lot of them. :)

 

As far as doing a 3D rendering engine on the TI, it's not impossible but there are definite technical problems to solve. You may find that it's not going to be viable applying another engine's approach, mainly because TI's bitmap mode is so completely different from anyone else's it may require a custom solution.

 

 

  • Like 1
Link to comment
Share on other sites

11 hours ago, FarmerPotato said:

Hey, I had that book too!
 

After 2001, I kept mostly OpenGL books. 
 

 

No book purges here (Blasphemy!). As a matter of fact, I have found that programming books written in the 80's and early 90's were of much better quality than most of the trash I find today. As a matter of fact, I have completely stopped purchasing programming-related books online, particularly Amazon, because I cannot really browse the book and judge its content. I only go to brick and mortar book stores for this.

  • Like 5
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...