Original Post

I haven’t posted in a while so I thought I’d just throw up a little graphics demo to show what I’ve been playing around with. Since I’ve never used C or ASM until Ben asked me to create our first translation patch I’ve been trying to overcome those small hurdles by experimenting as much as I can and bulding a small base of functions that can be used to create something bigger.

I think everyone hear should be able to tell what this demo is.

IT’S JUST A DEMO, DON’T READ INTO THIS ANYMORE THAN THAT :).

But hopefully it’s a start of better things to come.

Thanks.

Attachments:
23 Replies

Heeeey, it’s an Arwing! If that’s your first C program, then color me impressed (but with a slightly different angle for each eye)

Greg Stevens wrote:
IT’S JUST A DEMO, DON’T READ INTO THIS ANYMORE THAN THAT :).

Hmmm… so I guess this means we should NOT conclude that you are working on a full-fledged Star Fox game. πŸ˜‰

Thanks Greg, very nice.

Ben, your not trying to hint something there are you? πŸ˜‰

Greg Stevens wrote:

IT’S JUST A DEMO, DON’T READ INTO THIS ANYMORE THAN THAT :).

Wow, this looks pretty cool. Are there any plans for a card release?

VBmills wrote:

Ben, your not trying to hint something there are you? πŸ˜‰

Well, my winky face that I added may have actually been misleading, because I was truly trying to make sure that people do not assume that he is working on a Star Fox game, since I know that he is not. Nevertheless, the demo itself reveals that he has obviously been working on making wire-frame graphics, and it is logical to assume that he must be planning to make something much bigger than simply a demo, which will incorporate wire-frame graphics, but I’ll let Greg decide what all info he wants to reveal beyond that. πŸ™‚

Long story short yes I do plan on making a game. I’ve never actually made a game before and as many of the programmers here know it’s not something you just go and do on a weekend especially with 0 prior experience. I want my first game to use wireframe graphics and while I’ve never made a game before, I’m no amateur when it comes to programming since I do it for a living so I thought I could attempt to bite off a little more than perhaps a newbie to coding would attempt. I only have a few things left to learn/figure out before I can start on a game. While I can make a wire frame model and move it around in 3d space, I still need the routine to actually rotate the object around the 3 axis. I also need a collision detection algorithm and then I should be set. When I’m done I plan on releasing all my code since other programmers who have never attempted this before will probably benefit from a quick jump start. Since I’ve never coded in C before my code is simple and easy to understand by anybody who knows anything about C. I’m not breaking any new ground here, for example the Hunter source code available on this site has an extremely more advanced 3d engine for designing a game. But if I can use an analogy, sometimes you just need a Ford Escort to get you from point A to point B and not a Corvette. I’m going for the Escort and some simple functions that anybody can just add in to their code and create 3d wireframe graphics. It’s not going to be a full engine just a couple functions to handle the graphics and display.

While I can make a wire frame model and move it around in 3d space, I still need the routine to actually rotate the object around the 3 axis.

The best way to do this is with something called a transformation matrix. Basically, the concept is this: you take your input XYZ coordinates as a vector, multiply the transformation matrix by the vector, and the output is a new vector with your modified XYZ coordinates.

In 3D geometry, you’re going to want to use a 4×4 transformation matrix, and use 4×1 (rows, columns) vectors for your coordinate input. Why 4 when XYZ only accounts for 3 coordinates? For starters, you can’t perform a three-dimensional translation with a 3×3 transformation matrix. Further, the W coordinate is required for perspective projection, which is a non-linear transformation and therefore a transformation matrix in and of itself is insufficient.

When you want to modify a transformation, such as applying a rotation or translation, you simply populate a second transformation, then multiply them with each other to produce a new output matrix. It’s really quite handy.

The OpenGL documentation demonstrates the mathematics behind working with a model/view matrix:

* glRotate
* glScale
* glTranslate

Further, it provides calculations for a projection matrix. Projection matrices take world coordinates and convert them into normalized device coordinates. Basically what this means is: X = -1 is the left edge of the screen, Y = 1 is the top edge, Z = 1 is as far “into” the screen as a point can be, etc.

* glOrtho – In an orthographic projection, objects in the distance are the same size as objects up close.
* gluPerspective – A perspective projection simulates real-world perception of objects.

After applying the transformation matrix for projection, you then need to divide each of the X, Y and Z components by the W component to yield the final device coordinate.

Clear as mud? Great! If you need help, just let me know. (-:

I used OpenGL to realize a similar demo for Android a couple of years ago. It was surprisingly easy. I used Blender to build the 3D Model. Blender is a pretty powerful tool but I found it hard to learn in the beginning. However, I wrote a plugin for it that allowed me to export the 3D model directly to Java code. Would be pretty cool to have something similar for the VB.

Thanks for all the advice. I am aware of the transformation and rotation matrices and I am trying to implement them in my code. So far I have partial success. My challenges are that I’m trying to do everything with integer math so no floats and I’m also trying to use division quite sparingly since it’s an expensive operation. I am aware of fixed point integers which is basically what I’m implementing. For division I’m trying to adjust my values so every divide is just a power of 2 and I can shift it. I’m pretty sure that the compiler I’m using is not doing an arithmetic shift when I use >> and I just need to fix that. I’ll probably just use assembly for that routine since the SAR command should work just fine. I’m still learning and appreciate all the links. Thanks guys.

Greg Stevens wrote:
I’m pretty sure that the compiler I’m using is not doing an arithmetic shift when I use >> and I just need to fix that.

Compilers usually use arithmetic right shift on signed variables and ordinary right shift on unsigned variables. If you want to use arithmetic shift, make sure your variable is signed.

Yea it’s handling the signs correctly. I was really hoping that was my issue. It’s weird when I rotate my object to the right, so around the z axis it works great until I hit about 45 degrees. Then every line collapses into a straight line and then as you continue to rotate everything straightens itself out. I’m sure it’s something stupid I’m doing but I just haven’t seen it yet.

So when I rotate around the X and Y axis everything looks great. But no matter what I try the Z axis doesn’t work right. I’m still messing around so hopefully something will jump out at me.

Having already attempted this exact thing a few years back (with much less promising results…), I’m eagerly awaiting a look at that code.

I think my main problem was trying to get fancy with the line drawing algorithm. I found what the author purported to be “the fastest line algorithm in the world” and attempted to port it to VB. While I’ve never profiled or anything, I’m pretty sure that’s the bottleneck in my code.

Like thunderstruck, I also plan on making tools for model creation, but my platform of choice is Trimble’s (formerly Google’s) SketchUp. It’s a breeze to pick up and use, and the Ruby-based plugin API is a joy to work with.

Sometimes it’s just nice to sit back and watch smart people talk.

I think my main problem was trying to get fancy with the line drawing algorithm. I found what the author purported to be “the fastest line algorithm in the world” and attempted to port it to VB.

While I’m not ready to release all of my code yet, I think the algorithm I’m using is pretty solid for line drawing.

Here it is. I’ve used Assembly to try and optimize it (and learn ASM) but I left the original C code in place and just commented it.

This function also performs the projection calculation for x and y based on the z coordinate before drawing the line.

vector3d is just a typedef
typedef struct{
s32 x;
s32 y;
s32 z;
}vector3d

and p is parallax value which I use in my drawpoint function to offset the left and right screen buffers.

/*******************************
Bresenham Line Algorithm
*******************************/
void drawLine(vector3d v1, vector3d v2, u8 color, s16 p){
	if(v1.z>1)) || x1>(EYE_X+(SCREEN_WIDTH>>1))) return;
	if(y1<(EYE_Y-(SCREEN_HEIGHT>>1)) || y1>(EYE_Y+(SCREEN_HEIGHT>>1))) return;
	if(x2<(EYE_X-(SCREEN_WIDTH>>1)) || x2>(EYE_X+(SCREEN_WIDTH>>1))) return;
	if(y2<(EYE_Y-(SCREEN_HEIGHT>>1)) || y2>(EYE_Y+(SCREEN_HEIGHT>>1))) return;
	*/
	/**************************
	The following algorithm was taken from stack overflow
	http://stackoverflow.com/questions/5186939/algorithm-for-drawing-a-4-connected-line
	**************************/
	//dx=abs(x2-x1);
	//dy=abs(y2-y1);
	asm(
		"mov %2,r5\n" //x1
		"mov %3,r6\n" //x2
		"mov %4,r7\n" //y1
		"mov %5,r8\n" //y2
		"sub r6,r5\n"
		"bge _next1\n"
		"not r5,r5\n"
		"add 1,r5\n"
		"_next1:\n"
		"mov r5,%0\n"
		"sub r8,r7\n"
		"bge _next2\n"
		"not r7,r7\n"
		"add 1,r7\n"
		"_next2:\n"
		"mov r7,%1\n"
		:"=r"(dx),"=r"(dy)
		:"r"(v1.x),"r"(v2.x),"r"(v1.y),"r"(v2.y)
		:"r5","r6","r7","r8"
		);
	
	//sx = (x1

Thanks, Greg! Looks like it also handles some near-plane culling.

Does it really help to hand-optimize stuff like:

pixels = dx + dy;
e = 0;

I wouldn’t think there’d be much you could improve over the compiler’s version…

No, infact it might make it worse but like I said I was also doing it just to learn Assembly. Since my code isn’t complete yet I’m not even sure I’m going to keep the assembly in it if I don’t really notice any speed differences but I haven’t benchmarked anything yet so I can’t be sure. And actually it doesn’t really handle near plane culling. I just simply don’t draw the line if the z value of either end is less than the projection plane z value because it produces some really funky results. Same with the X and Y values but I commented those out and am not currently using that code. I did notice that the virtual boy automatically wraps coordinates to the other side of the screen if they go outside the screen bounds. Maybe there is an obvious reason as to why but I thought it would only do that for BGMaps and Worlds if the OVR[something] flag was set. So if any object goes off the right side of the screen it automatically appears on the left hand side without having to do any special coding. I’m actually going to have to do coding to remove that “feature” if I can’t find a flag or register that is causing that to happen.

Well, not that anybody probably cares but I solved my Z axis issue. I just needed a few extra temp variables because I was clobbering some values before I acutally needed them. So I can now rotate my objects around all 3 axis. Next I need to rotate an object around an arbitrary vector and I should be done with my rotation matrix code. I’m going to bed….

Here is the Arwing able to be rotated around all 3 axis. Just use the left D-Pad for the Z and X axis and the right D-Pad for the Y.

This uses transformation matrices for all rotations.
I think it’s a pretty good start. I still have a lot to learn though.
Wishing I paid better attention in math class when I was younger…

Attachments:

I just tried it and it looks great. One minor thing I noticed: When I do the rotation using the left d-pad (right and left) it looks like some lines are doubled (You can see it best on the tip of the Arwing). I though it was strange because it didn’t occur during the other rotations.

I know this is still in an early state but do you consider sharing the way you store the model coordinates? In that case I could look into blender again and try to convert some other models.

 

Write a reply

You must be logged in to reply to this topic.