News - nuwen.net

So high, so low, so many things to know

Theresa

News


stl@nuwen.net

3/13/2010 - Version 5.2 of my MinGW Distro is 13.8 MB, because I am a wizard. A very tiny wizard.

3/2/2010 - Version 5.1 of my MinGW Distro updates Boost to 1.42.0.

1/6/2010 - Version 5.0 of my MinGW Distro updates GCC to 4.4.1 and libpng to 1.4.0. It appears that I wasn't hallucinating back in May; GCC 4.4.0 had a bug, fixed in 4.4.1, that caused it to miscompile MPFR, one of the libraries that it depends on.

1/1/2010 - Version 4.3 of my MinGW Distro brings all of its components up to date, including Boost 1.41.0, except for GCC (which I'll struggle with later).

I've also added 3 scans to my increasingly misnamed SF Reviews page.

12/23/2009 - I've finally finished moving nuwen.net to Linode, saving an incredible amount of money. (My dedicated server at Rackspace cost $325/mo, while my virtual server at Linode costs $17.96/mo.) Everything appears to be running perfectly, but if you notice any problems, please tell me.

6/30/2009 - I've added 4 scans to my SF Reviews page.

In the very near future, nuwen.net will be changing hosts from Rackspace to Linode. There shouldn't be any observable interruption of service, but the Internet is full of lies and kittens, so you never know.

5/18/2009 - Version 4.2 of my MinGW Distro updates Boost to 1.39.0.

I tried to build GCC 4.4.0, but it kept miscompiling itself. Here's what it looked like:

C:\Temp>type meow.cc
#include <iostream>
#include <ostream>
using namespace std;

int main() {
    double f = 900.5;

    cout << "Plain: " << f << endl;
}

C:\Temp>g++ -Wall -Wextra meow.cc -o meow-good.exe

C:\Temp>meow-good
Plain: 900.5

C:\Temp>meow-bad
Plain: >C.AFFG

I wasted an incredible amount of time on this; I'll give GCC 4.4.1 a try when it comes out.

3/22/2009 - I've scanned 11 more books for my SF Reviews page.

I've been extremely busy, but while you're waiting for me to get back to working on this site and Spacetimewar, you can read my posts Lambdas, auto, and static_assert: C++0x Features in VC10, Part 1 and Rvalue References: C++0x Features in VC10, Part 2 over at VCBlog.

2/22/2009 - Version 4.1 of my MinGW Distro updates Boost to 1.38.0 and GCC to 4.3.3. The 4.x distros use TDM's GCC patches; beginning with the 4.1 distro, I encode this into GCC's version number. (For example, 4.3.3-dw2-tdm-1 .)

12/31/2008 - Version 4.0 of my MinGW Distro updates GCC to 4.3.2.

Over the last two months, I've been extremely busy with work, Christmas stuff, and building the new distro, in that order. Now that I'm done with everything, I can resume working on Spacetimewar.

11/9/2008 - Version 3.14 of my MinGW Distro updates Boost to 1.37.0.

10/20/2008 - This was harder than you'd think, but easier than I thought:

Spacetimewar's Transparent Text
Spacetimewar's Transparent Text

What was the trick? Well, what FreeType actually rasterizes and what I want to draw on the screen are very different. FreeType, being a general-purpose font rasterization library, consumes vector fonts and produces bitmaps for a given font size. (Actually, what it produces is even better. It produces "spans", of the form "Beginning at X = 4, Y = 7, there is a horizontal span of 137 pixels with 255 coverage", where "255 coverage" means "fully opaque". Spans can be easily used to produce bitmaps, and they can also be easily used to gather various metrics, such as the size of each character glyph.) FreeType is extra awesome in that it contains a "stroker", which can generate borders for font outlines.

After rasterization, each character glyph, which I call the "core", looks like what I draw on the screen. (Because it consists of coverage information, it doesn't have a color, but it can be easily painted with a color, even a gradient, as I have done.) When using a stroker, rasterization emits a second bitmap (actually spans, as before), which I call the "border". However, the border actually covers the area of the core, plus a little around the edges.

Now that we've gotten the core and border bitmaps, what does it take to actually draw something on the screen? Rendering text efficiently (actually, rendering anything efficiently) involves arranging things so that the video card does the heavy lifting. Today's video cards are insanely powerful, especially for 2D graphics, but you have to use them properly. Drawing an image on the screen is as simple as loading it into a texture and drawing a textured quadrilateral (this is what I've been doing for over a year with the various JPEGs and PNGs in my screenshots, such as the background starfield). Similarly, rendering text efficiently means using textures. For simplicity, it's easy to imagine creating one texture per character, and rendering textured quad after textured quad with different textures. That works, but it's slow - switching textures is expensive for video cards to do, when you're doing it for every character in a string. Instead, if you create one texture for the whole font (often called a "mosaic texture"), and render every character in the alphabet (and all of the symbols) into that texture, then you can texture quads with subregions of the master texture. Video cards really like that, and reward you with speed.

Imagine that you're drawing character after character in this manner. You've got a problem - characters can overlap, especially when you've given them fancy borders. But in the string MEOW, we don't want the E's border to cover up any part of the M's core. We want the borders for all characters to be behind the cores for all characters. Therefore, we need to render text in two passes: first, a set of textured quads consisting of MEOW's borders, and then another set of textured quads on top consisting of MEOW's cores. That solves the overlapping problem (it's okay when borders overlap borders or cores overlap cores, since they're the same color - this is true even for gradient coloring). It's not really more expensive, either - you're rendering twice as many quads, but that's really cheap. You're still using a single mosaic texture, and simply retrieving the border and core information from it separately. (I'm skipping over the details of how this is done - in particular, vertex shaders and pixel shaders are doing the heavy lifting here.)

So that's awesome. Now what's the problem? Well, if you're really hardcore, you won't be satisfied with perfectly antialiased, gradient colored, bordered (and separately gradient colored) text. You want more: transparent text. However, if you make your cores transparent, your terrible secret will be revealed: you've got borders underneath. Instead, you want to preserve the illusion that the borders surround the cores. (Why not simply stamp the core on top of the border of each character glyph? Remember, overlapping.)

In the end, I solved this by using depth buffering. Yes, depth buffering, in my 2D game which previously had no use for it. It turns out that pixel shaders can emit depth values, so instead of drawing the borders and then the cores, you can draw the cores and then the borders. While drawing the cores, you emit close depth values. While drawing the borders, you emit far depth values. In that manner, the borders won't overdraw any pixels covered by the cores. Then you do something sneaky in order to deal with core pixels that have partial coverage (these occur on the antialiased edges of the core glyph), because otherwise you'd draw a partial core pixel without any border, leading to ugly gaps.

Finally, you go back and fix borderless text (which you broke by making your calculations assume that they could divide by certain border metrics, leading to division by zero), and you fine-tune your calculations to make pixel and subpixel-wide borders work. And you (or I) get this:

Zero, Half, And One Pixel Borders
Zero, Half, And One Pixel Borders

Subpixel borders are a special challenge, because they lead to pixels that are partially covered by the core, partially covered by the (very thin) border, and partially uncovered. With larger borders, you can assume that pixels partially covered by the core are otherwise fully covered by the border. Here's everything put together:

Spacetimewar's Advanced Text Rendering
Spacetimewar's Advanced Text Rendering

What's left? Resolution independence.

10/12/2008 - Version 3.13 of my MinGW Distro fixes a libpng security vulnerability.

10/10/2008 - I've made more progress on Spacetimewar:

Spacetimewar's Gradient Colored Text
Spacetimewar's Gradient Colored Text

Look closely - I'm applying gradient coloring to both the core and border of each letter, because I can.

I still have to deal with different resolutions. Also, there's something tricky that I have to do in order to be able to fade my text in and out.

9/21/2008 - Version 3.12 of my MinGW Distro patches freetype and libjpeg.

Version 2.0.1.0 of libnuwen adds sequence container typedefs for float and double , and removes an obnoxious dependency on Boost.Lambda.

These dual updates can mean only one thing: I've been working on Spacetimewar!

Spacetimewar Using FreeType
Spacetimewar Using FreeType

I've rendered this screenshot without antialiasing in order to demonstrate an important point: rendering fonts with FreeType instead of with polygons means that Spacetimewar's text will be antialiased regardless of whether your video driver is antialiasing polygons. It gets better: FreeType's antialiasing is perfect, because it's mathematically computing exact pixel coverage (through black magic that I'm glad I didn't have to write). Polygon antialiasing doesn't pretend to be mathematically exact. And yes, this is all being rendered at 372 frames per second. Note that instead of timing how long it takes to render a single frame and then taking the inverse of that, I simply count how many frames I've rendered in the last 2 seconds and divide by 2.

Also, FreeType allows me to draw borders around text, which massively enhances its readability against busy backgrounds. This was fundamentally impossible when I was using polygonal text (without resorting to completely disgusting hacks).

What remains to be done, before I actually start working on the game itself? You'll notice that I haven't reimplemented gradient coloring on text yet, or any coloring whatsoever. I'll be doing this with pixel shaders. In fact, I'm already using pixel shaders to render all text, so extending them will be easy. There's also some work that I have to do in order to accomodate different resolutions, because not everyone runs 1920x1200 like I do. Spacetimewar is a resolution-independent 2D game, as I hate fixed-resolution 2D games with a burning fury. (You'll get letterboxing or pillarboxing if your monitor doesn't have a 16:10 aspect ratio; distorting aspect ratios is thoughtcrime.) Since I've carefully designed the engine to be resolution-independent, all that I need to do is avoid graphics that'll become obnoxiously tiny or horribly aliased at my minimum supported resolution. However, pixel-perfect graphics are an exception. One example is the cursor (I'm still deciding what to do about that; I'm not happy with its current implementation), and the other example is text rendered with FreeType. Such text can't be resized or translated to non-pixel boundaries without significantly degrading its quality. Therefore, I'll have to write a special codepath that deals with non-1920x1200 resolutions. (Internally, Spacetimewar renders to a "virtual" resolution of 1920x1200; I'm going to have to place UI elements and the like somewhere, and I may as well do it according to my own monitor's coordinates.)

I haven't had time to review any SF novels as I had planned; the beginning of this month was completely annihilated by having to fly to Colorado for a week due to a medical emergency (not mine). And as for the rest of the month, whenever I'm inspired to work on Spacetimewar, that supersedes everything else.

8/22/2008 - Version 3.11 of my MinGW Distro is a minor update.

8/16/2008 - And by "tomorrow", I meant "this weekend". You are in a maze of twisty updates, all different:

I have a few more things to mention about the games that consumed my life recently:

For me, one of the most "emergent" things about GTA4 was finding cars. The Turismo sports car is one of the best cars in the game (I compared it to the other sports cars, but not extensively, since I kept coming back to the Turismo). "Best" means "accelerates well", "handles well", and "doesn't explode". As the Turismo has its engine in the back, the game's damage model makes it almost invulnerable, which is nice. They're rare, and they're consumable (if driven into the water). So, this led to a minigame for me: find and collect every Turismo in sight. By the time I was done, I had parked two Turismos in front of each of my safe houses.

Playing D&D 4e is a remarkable turn of events for me. When I was at Caltech, I used to laugh at the people who played D&D in a common room. Of course, I had been exposed to the game system through Neverwinter Nights and Knights Of The Old Republic, but playing the tabletop game seemed strange to me. Later, I flirted with playing 3.5e with a few friends, but that petered out quickly. 3.5e's rules were stupidly complex (I can keep track of complicated rules - that's my day job, after all - but not stupid rules, like "full attacks"), and I hated the Vancian magic system ("fire and forget"; the less you know about it, the better). Recently, I heard about how 4e had simplified the rules and eliminated Vancian magic, which immediately hooked me. Indeed, 4e's rules make a lot more sense, and low-level wizards are actually fun to play now. In fact, I've gone so far as to DM a campaign for my best friend, who is controlling 6 PCs simultaneously. It's great fun, but also time-consuming; fortunately, it's not all-devouring like a video game would be.

Geometry Wars 2 fixes all of the things that I disliked about the first one (insanely rapid difficulty progression and insanely nasty penalties for death), and looks way better. Now I've got to make Spacetimewar look as good.

Go play Braid, if you haven't heard about it already. I like to call it, A Lesson Is Learned But The Damage Is Reversible.

8/14/2008 - I return!

Where did I go? To places called GTA4, D&D 4th Edition, Geometry Wars 2, and Braid. And work, although I have far fewer magical powers there. Now that I'm back, thanks to the finiteness of my addictions, I'm working on nuwen.net again, and will soon resume working on Spacetimewar.

Version 3.10 of my MinGW Distro contains Boost 1.36.0.

I've read and scanned several more SF novels, and I bought a new copy of Walden Two to scan. I've gotten several mails about my lack of reviews; I plan to start reviewing books this weekend.

I've renamed the Index page to the News page, which accurately describes it, although I haven't changed its URL. That reminds me: nuwen.net is now 8 years old, ignoring name changes. And I am now 25.

When I paused working on Spacetimewar, I had successfully replaced my font rendering code with FreeType. Now I just have to reimplement gradient coloring.

More tomorrow.

5/19/2008 - Version 3.9 of my MinGW Distro is now available.

5/5/2008 - Version 3.8 of my MinGW Distro contains a functionality fix for GNU make and a security fix for libpng.

Recently, I've been working on Spacetimewar:

Spacetimewar Renderer (With Background)
Spacetimewar Renderer (With Background)

Spacetimewar Renderer (Without Background)
Spacetimewar Renderer (Without Background)

Aside from making the renderer use vertex buffer objects for increased speed, and removing a special (and slow) codepath for non-power-of-two textures (which OpenGL 2.0, now my minimum requirement, supports natively), I've added machinery for OpenGL shaders. I implemented photosphere and corona shaders to make my awesome sun.

The only thing left to do before I write the game engine itself is to replace my font rendering code with FreeType, for kerning and borders.

Older News

About This Site

What is nuwen.net?

A collection of things which are intended to be useful to readers.

This type of site, with its focus on useful things, is now rather unusual. It is different from a blog, which (being chronologically organized) is about events. It is also different from a journal, which is a blog about people. While my chronologically organized news posts often talk about events (sometimes sounding suspiciously blog-like) and myself (sometimes sounding suspiciously journal-like), neither the news posts nor myself are the focus of this site. The news posts are fundamentally a ChangeLog for the real stars of this show: the pages about stuff.

John Walker's fourmilab.ch is a larger example of this sort of thing. It was, and continues to be, the inspiration for nuwen.net.

Who writes nuwen.net?

As the footer on each of my pages mentions, my name is Stephan T. Lavavej. To learn more about me, including my elusive middle name, see my personal page.

You can help me improve my writing by sending me feedback. Do you like what I've written? Do you dislike it? Is something broken? How did you get here? (Through a search engine? From another site? Etc.) Please E-mail me at stl@nuwen.net with your thoughts.

How long has nuwen.net existed?

Since June 5, 2000, although it experienced a few name changes before receiving its current and permanent name.

How is "nuwen" pronounced, and what does it mean?

It's pronounced "noo-when", and it's a reference to my favorite character, Pham Nuwen, in my favorite science fiction novel, A Deepness In The Sky by Vernor Vinge ("vin-jee"). The novel implies that this far-future last name is derived from today's Nguyen. And Pham rhymes with "ROM", although I usually mispronounce it to rhyme with "RAM".

In actuality, the name of this site is a subtle hint that you should read A Deepness In The Sky and its sequel A Fire Upon The Deep. Both novels are extremely rich in concepts and terminology, which I delight in referring to.


http://nuwen.net/index.html
Stephan T. Lavavej
stl@nuwen.net
Updated 3/13/2010.