Game Development Community

Flat Tile to Isometric

by Greg Tedder · 05/24/2008 (6:24 pm) · 12 comments

I just tried to put this on the forums, but it was too big, so I put it here.

I finally broke into the code this weekend. I have barely touched C++ in the last 3 years and was surprised at how easy it was to jump into. So, as my first little stab at getting used to the source, I decided to play with the quad rendering in t2dStaticSprite and t2dAnimatedSprite. I wanted to see how an isometric textured quad would render compared to an actual isometric tile. I don't know which I really like better, so I am probably going to go with the new technique. I also spent several hours trying to track down the script that managed editing it in the level editor, so it's as easy as checking a box to try it out.

First off, add these members and methods to t2dStaticSprite.h:

bool                            mIsometric; // with the others at top

bool setIsometric(bool isISO);   // put in the public area
bool getIsometric();

Now go to t2dStaticSprite.cc and add these:

ConsoleMethod(t2dStaticSprite, setIsometric, bool, 3, 3, "(bool isometric) - Sets the tile to isometric.\n"
                                                         "@return Returns true on success.") 
{
 //object->setVisible( dAtob(argv[2]) );
  // bool iso = (bool)argv[2];
   object->setIsometric( dAtob(argv[2]) );
   return true;
}
bool t2dStaticSprite::setIsometric(bool mISO) {
   mIsometric = mISO;
   return true; // you might actually want to check something here :-)
}


ConsoleMethod(t2dStaticSprite, getIsometric, bool, 2, 2, "() - Gets whether or not this is an isometric tile.\n"
                                                         "@return (bool isometric) The boolean.")
{
   return object->getIsometric();
   
}
bool t2dStaticSprite::getIsometric() {
   return mIsometric;
}

In the renderObject method, we need to change how the quad is rendered when isometric is checked. So change that small block of quad rendering code to include this logic and add the isometric rendering code below.

if(!mIsometric) {
		    // Draw Object.
          glBegin(GL_QUADS);
            glTexCoord2f( minX, minY );
            glVertex2fv ( (GLfloat*)&(mWorldClipBoundary[0]) );
            glTexCoord2f( maxX, minY );
            glVertex2fv ( (GLfloat*)&(mWorldClipBoundary[1]) );
            glTexCoord2f( maxX, maxY );
            glVertex2fv ( (GLfloat*)&(mWorldClipBoundary[2]) );
            glTexCoord2f( minX, maxY );
            glVertex2fv ( (GLfloat*)&(mWorldClipBoundary[3]) );
          glEnd();
      } else {
          // Draw ISO Object
          glBegin(GL_QUADS);
            glTexCoord2f( minX, minY );
            t2dVector v = ( getHalfSize() );
            F32 x = (mWorldClipBoundary[0].mX) + v.mX;
            glVertex2f( x, mWorldClipBoundary[0].mY );
            glTexCoord2f( maxX, minY );
            F32 y = (mWorldClipBoundary[1].mY) + v.mY;
            glVertex2f( mWorldClipBoundary[1].mX, y );
            glTexCoord2f( maxX, maxY );
            x = mWorldClipBoundary[2].mX - v.mX;
            glVertex2f( x, mWorldClipBoundary[2].mY );
            glTexCoord2f( minX, maxY );
            y = mWorldClipBoundary[3].mY - v.mY;
            glVertex2f( mWorldClipBoundary[3].mX, y );
          glEnd();
       }

Now there is another method called initPersistFields where we need to add this code. I commented out the last part because I kept getting errors and never figured it out, but this much works for all points and purposes.

addField("isometric", TypeBool, Offset(mIsometric, t2dStaticSprite) );//, &setIsometric, &defaultProtectedGetFn, "" );

Just one more stop in the code, and then we get to editing TGB's editor forms. You need to add the last line 'mIsometric(false)' to the constructor to make it read like this.

t2dStaticSprite::t2dStaticSprite() :    T2D_Stream_HeaderID(makeFourCCTag('2','D','S','S')),
                                        mImageMapDataBlock(NULL),
                                        mImageMapDataBlockName(NULL),
                                        mFrame(0),
                                        mIsometric(false)
{
}

Now go into the Torque game builder directory and navigate to: tgb/tools/levelEditor/scripts/forms/quickEditClasses/t2dStaticSprite.ed.cs. In the CreateContent method, add this line before the function returns.

%rollout.createCheckBox ("Isometric", "Isometric", "Is this isometric");

That should be it. Now you can take a square tile and render it with an isometric look by checking the Isometric check box in the level editor. To do this to t2dAnimatedSprite, just follow the exact same steps. You will find an exact replica of the quad rendering code there, and the level editor script for animated is found in the same directory as for the static.

This was all done on a mac, so I am not completely confident in it working with Visual Studio.

www.codeugly.com:12001/images/aegesroad/beforenafteriso.png

#1
05/24/2008 (6:47 pm)
Can you slap a screenshot of the before and after?
#2
05/24/2008 (8:18 pm)
Wow, sounds fantastic! :)
#3
05/25/2008 (6:12 am)
The best part of this is the seamless edge you can get even with smoothing on, and it zooms well too. I am sure a good pixel artist could tip the scales on comparison though.
#4
05/25/2008 (12:29 pm)
Nice!!! I like this one. Maybe it has potential to become included in the official distribution.
#5
05/25/2008 (12:47 pm)
Very nice, Greg. I think I'll try this one out in Visual Studio. I actually had a game idea that could use this. :)
#6
05/25/2008 (3:48 pm)
Okay I don't understand what this is at all from the screenshot. It looks like the After part has better detail than the before part. Is that the difference?
#7
05/25/2008 (5:09 pm)
So this allows you to make isometric tilemaps using the built in tilemap editor? That's pretty cool.

I don't see any reason why it won't work the same on windows, it's not calling any platform specific code.
:)
#8
05/25/2008 (9:05 pm)
@ Jeremy

Yes, it was to show the improvement. When using smoothing with the isometric tiles it blur the edges and makes it difficult to make them seamless, so I usually can't bring out much detail in the tiles without having edges. With the new tile I can render it with much higher contrast and detail and get a crisp edge to work with .

@Michael

I kinda doubt they would want it in the official because it adds an extra logic call per tile per rendering cycle, but hopefully people who need it will find it useful. :-) I could have used this a few months ago.

@ Chris and Joe

Yeah, I figure it would work in Visual Studio, but stranger things have happened between compilers. Let me know how it goes.
#9
05/25/2008 (9:06 pm)
What is an isometric tile?
#10
05/26/2008 (8:02 am)
Isometric is a form of 2d perspective. In top-down, the tiles are usually square, but always rectangular. In isometric, the tiles look like most of the tiles in the image above. They appear turned 45 degrees and squashed. The most popular ration for an isometric tile is 2:1, though there are others.

Check out these two links.

http://en.wikipedia.org/wiki/Isometric_projection

http://illuminations.nctm.org/ActivityDetail.aspx?ID=125
#11
11/26/2009 (5:19 pm)
A screenshot of the before and after would be nice to see.
#12
11/27/2009 (12:28 am)
genius!

does this work on windows?