Warscale Blog 98 - Swinger and a feature adjustment request
by Guimo · 11/03/2011 (4:40 am) · 6 comments
Hi everybody!
Its a very very long time with no blog. Basically I got really burned on Warscale and I really needed time for myself. Baing an indie is very demanding on time and I needed time for my family.
But after a while I got bored of not doing anything with my time so I was doing a lot of different things while my head was sorting out Warscale.
First swing - Node.js
My first swing during that time was about Javascript. More specifically Node.js. If you havent seen it, Node.js is a binary which is able to translate javascript programs. Just like Torque and Torquescript, but you remove all the 3D engine sections and keep the network and script interpreter but all in javascript.
So, once you get the idea, its so easy to implement a chat using web browsers and javascript and of course there come a prototype game (not allowed to say what as is a friend's idea) using Node.js and javascript. Quite interesting.
And this small experiment made me realize how powerful Linux can be as a game server. I mean, I use Linux everyday at work, I'm a nominated Systems and Database manager for my development team. I have to keep the JBoss, postgresql and other services of our system up and running so I'm not unfamiliar to the environment but I never made myself to get into it.
The only problem I got is that all my game logic is based on TorqueScript files, and I just can't run it on Javascript. A shame because its a nice environment. A nice swing, but will stay with T3D.
Second swing - Windows for Linux
I mentioned in previous mails, the main problem on Warscale is the hosting. I really planned to host at home on a Windows machine but my ISP (Telstra Australia) could not solve a problem I have about my internet connection dropping any time I get a phone call on my landline and the computer I planned to use as server just crashed at any time with no pattern at all.
Of course all that could be solved by getting a dedicated virtual host. But Warscale run on Windows only and that is at least twice more expensive. Not that I can't pay the host, its just I find it a loss of resources when I can solve the problem by compiling the product for Linux and then get a more powerful host with the same money.
So I got into the problem of compiling the engine for Linux... or swinging to Linux as I call it. Of course I'm using TGE as my backend so it was supposed to be easy. Big mistake. But you learn from mistakes and I learned a LOT.
The first thing was attempting to compile, and I just heaps of errors. Mainly because I was trying to compile on an Linux x64 version and Torque is designed to run on 32bit architectures.
Fortunately a lot of people have run into the same problem and if you dig here and there you will find bits of knowledge that may help you a lot.
Even so, my learning was slow and at one point I even managed to strip all the 3D, GUI, sound and texture support from the engine getting a bare network + torquescript engine which is enough for Warscale. But on the end I decided and compiled the whole thing.
In the way I learned so many things ("yum provides" is my new BFF compiler wise) that finally after one week of work I was able to compile all the engine, as 32 bit on a 64 bit machine and run it. Of course I only required the dedicated compilation so I don't know (and don't care) if it runs on Linux X11.
At the end, I compiled everything on a 32Bit linux and I'm running fine. And the best thing, the T3D system connects with the Warscale TGE based server as they were both born one for each other.
Third swing - MySql and PostgreSQL
I have switched databases in the game. I remember I started using Oracle. Then SQLServer, then MySQL... but lately I have been using Postgresql so much that I really feel comfortable with it. I'm not really sure that will be my last database, but looks fine and sturdier than MySQL so fine for me. And to be honest, for some reason, I just lost confidence on mySQL after Oracle got it. I don't know why.
I used a small program called Navicat to move the DB from MySQL to PostgresQL and it was a breeze. I'm using SQLAPI to connect to the DB so switching from one DB to other is as simple as changing your connection string. I'm still on MySQL but ready to change anytime.
Fourth swing - T3D!!!!
I decided to bite the bullet and update all my code to T3D. And that includes rewriting a lot of controls which I updated in TGE with specific functionality for Warscale (bitmap borders, scrolls, MLText and others). I'm slowly going there. At least I got into the LoginScreen!
The one with a purple background is T3D, the brown one is TGE.
Now if you are a good observer, you wil notice there is a problem with the buttons. They really look different. Try overlapping both images using GIMP or Photoshop then turn on and off one of the layers. Other than some slight problems in the text position, everything is right. Pixel by pixel both login screens match with extremely good precision except for the buttons.
Here, take a look at the buttons. Enlarge and compare. You will definitely notice the TGE buttons look better while the T3D buttons look pixelated
So I was baffled. Of course the original bitmap size for those buttons is larger than the buttons so they are being stretched down. I remember having such problem a long time ago while programming my own game engine (KEngine3D) and I remembered the problem being something on the filtering mode. So I started my search in the T3D engine and found the following function:
gfxDrawUtil.cpp : Line 335
void GFXDrawUtil::drawBitmapStretchSR( GFXTextureObject* texture, const RectF &dstRect, const RectF &srcRect, const GFXBitmapFlip in_flip /*= GFXBitmapFlip_None*/, const GFXTextureFilterType filter /*= GFXTextureFilterPoint */ , bool in_wrap /*= true*/ )
So this function tells us the texture filtering mode for drawing bitmaps in T3D is GFXTextureFilterPoint. That is, a point filter. For those who don't know what I'm talking about, when a point filter is used, whenever the engine needs to decide which point to render from the texture, it just picks the one under the texture UV coordinate. It saves time because no interpolation is done. Point filter is great for faster renders, but the problem is you lose quality and that is a must in many 2D operations.
Well, fortunately there is another filtering mode exposed by the engine which is the GFXTextureFilterLinear. A linear filter works by interpolating a color based on the contributions from surrounding pixels in a weighted average so the result is softer but takes longer to process. But boy the difference is worth it.
I guess it is the decision of GarageGames to default to a point filter instead of a linear filter so the engine goes for speed instead of quality. But if you want 2D rendering quality, go to gfxDrawUtil.h and change the default rendering modes on all the functions from lines 79 to 87 setting the filter mode of the stretch operations to linear. No need to do this for the non stretch versions.
But if you just want a less radical fix for this specific problem, go to guiBitmapButtonCtrl.cpp and change line 483 for this one:
GFX->getDrawUtil()->drawBitmapStretch( texture, rect, GFXBitmapFlip_None, GFXTextureFilterLinear );
Thus forcing the linear filter to work.
How much difference does it make? Well, judge for yourself!
I don't know you but I know what I want. 2D stuff is usually so precise that I would always go for quality and not speed in this case. Your choice Garagegames. At least consider this for stretchs.
Luck!
Guimo
#2
I've also got some custom GUI controls and tweaks in TGE, and would like to port them over to T3D. What difficulties or issues did you find when porting your controls over?
11/03/2011 (8:45 am)
Hey, while I'm thinking about it...I've also got some custom GUI controls and tweaks in TGE, and would like to port them over to T3D. What difficulties or issues did you find when porting your controls over?
#3
11/03/2011 (10:35 am)
I think this is a candidate for default to the linear filter and expose the field to the console and the editor so you can choose point (or none) of you know it won't be scaled, or won't be scaled very far.
#4
11/03/2011 (11:07 am)
hmm yeah, not sure about Australia. But here in the US "Swinger" has a completley different meaning lol.
#5
a. textureHandler is now called textureObject.
b. You cant access mBounds to get the extent (mBounds.extent). Now you have to use getExtent()
c. The rendering methods are now available in the GFX library. Slightly different parameters but basically the same.
e. ConsoleMethod function doesn't require to specify the number of parameter.
f. There is a fancy macro to add callback methods for input events called IMPLEMENT_CALLBACK. You can then later call it as myCallbackName_callback(parameters);
You are not required to define things this way and you can still use ConsoleMethod.
g. And changes to the headers. Nothing critical.
Keep those in mind and you will be fine.
@James - Completely intentional. It has exactly the same meaning. But I'm still faithful to Warscale :)
11/03/2011 (12:26 pm)
@Kevin - I have found everything is fairly similara. textureHandler is now called textureObject.
b. You cant access mBounds to get the extent (mBounds.extent). Now you have to use getExtent()
c. The rendering methods are now available in the GFX library. Slightly different parameters but basically the same.
e. ConsoleMethod function doesn't require to specify the number of parameter.
f. There is a fancy macro to add callback methods for input events called IMPLEMENT_CALLBACK. You can then later call it as myCallbackName_callback(parameters);
You are not required to define things this way and you can still use ConsoleMethod.
g. And changes to the headers. Nothing critical.
Keep those in mind and you will be fine.
@James - Completely intentional. It has exactly the same meaning. But I'm still faithful to Warscale :)

Torque 3D Owner Kevin Rogers