Creating Graphics with TEXTURES

TEXTURES (also known under the deprecated name of HIRESTEX) is ZDoom's text-based answer to the classic Doom engine PNAMES and TEXTUREx lumps. With TEXTURES, you can create not only new textures and flats, but also menu graphics and sprites. Here's the relevant Wiki page for it, and a couple of other pages which will be referenced.
Adding a TEXTURES lump is easy. Simply create a new entry named TEXTURES, or if you're using the PK3 format for your mod, create a text file named TEXTURES. This language is plain-text and can be edited with any text editor, or in a resource manager such as XWE or SLADE. SLADE is recommended as it features a visual TEXTURES editor, though you can still of course edit the code directly.

First of all, here are some relevant keywords. This first batch will help you learn the namespaces involved with TEXTURES.
  • Texture - This creates an "overriding" texture (see note on priority below). Most of the time, this is what you will want to use.
  • WallTexture - Used to define a wall graphic. This is usually not necessary in ZDoom.
  • Flat - Used to define a floor or ceiling graphic. This is usually not necessary in ZDoom.
  • Sprite - Used to define a sprite, an image displayed for weapons, enemies, projectiles, decorations and other physical objects. Sprites have special properties in TEXTURES which I will cover later.
  • Graphic - Used to define a graphic like M_DOOM or menu images. Needed only for PK3 archives, and not WADs.
A note on texture priority: There are three texture namespaces, Texture, WallTexture and Flat. When applying a texture on a sidedef, ZDoom will look first in Texture, then in WallTexture, and finally in Flat. When applying a texture on a sector, ZDoom will look first in Texture, then in Flat, and finally in WallTexture. This second batch can be applied to the images you create with TEXTURES.
  • XScale - The width scaling of the image. This uses inverted scaling, covered later.
  • YScale - The same as XScale, but for height.
  • Offset - Used only for sprites to determine where it is displayed when it is rendered.
  • WorldPanning - This is mostly used when replacing a lower-res texture with a higher-res one. As such, it's not terribly useful.
  • NoDecals - This image will never have decals on it in a map.
  • NullTexture - Most likely for compatibility purposes to emulate textures like AASHITTY and AASTINKY. This texture will never be drawn.

I'll show you how to assemble a basic single-patch texture, followed by a detailed analysis of it. This is a texture from Doom 2's TEXTURE1 lump. In a PK3 archive, you can also specify a full path if you want to.

walltexture ASHWALL2, 64, 128 //namespace, name, width, height
{
   Patch RW22_1, 0, 0 //patch name, offset X, offset Y
}

As you can see, you begin a new entry by defining a namespace as explained earlier. For a simple texture, like in Doom 2, I am using the walltexture namespace. Following this is the name of the texture. We're using the name of the first texture in Doom 2's TEXTURE1 lump after AASHITTY, which is ASHWALL2, for example purposes. Next, the width (X) of the image in pixels, and then the height (Y) in pixels.

Next, we place a patch. You begin with the keyword Patch, followed by the patch you wish to use. This can be any graphic in the WAD you're using. After the patch are it's offsets on the final texture. These are X and Y, respectively. 0, 0 would be the upper-leftmost pixel.

Finally, a second curly brace to close the block, and we have a functional texture! It's not much, but it's a working texture. Why don't we spruce it up a bit, though? Let's re-use our texture, but this time, we're making a sub-block underneath the patch. Here we can apply a number of neat effects, but to start I'll show you color blends.

walltexture ASHWALL2, 64, 128
{
   Patch RW22_1, 0, 0
   {
      Blend Red, 0.5 //color, intensity
   }
}

As you can see, I've blended some red into the patch at half intensity. At 0.1, the graphic is an almost entirely solid color, while at 0.9, it's a very light tint, opposite what you may expect.


Now I'll show you how to use translations. We're going to take FLAT14, which is a blue carpet-looking flat from Doom 2, and make it red. So, first we define our image, but you know how to do that by now. If you've written translations in DECORATE or ACS, this is easy as can be, and it uses the same syntax.

flat FLAT14_R, 64, 64
{
   Patch FLAT14, 0, 0
   {
      Translation "192:207=176:191", "240:247=40:47"
   }
}

As you can see, I've added the Translation keyword, followed by my crappy translation that turns the soft blues of the image into reds. You can also use GZDoom's special translation function to use colors outside the palette. Here's a fabulous purple carpet which shows off this feature's use in TEXTURES.

flat FLAT14_P, 64, 64
{
   Patch FLAT14, 0, 0
   {
      Translation "204:207=[130,80,170]:[80,30,120]", "241:247=[75,25,110]:[55,5,90]"
   }
}
Bear in mind that Translation and Blend cannot be used on the same patch!

Next comes rotations. These are also easy to do, and applied in much the same way as flips. For an example, I will show you how to make a practical texture out of an existing one; we're making a horizontal version of the DOORTRAK texture.

texture DOORTRKH, 128, 8
{
   Patch DOORTRAK, 0, 0
   {
      Rotate 90
   }
}

First of all, note the dimensions of the texture; when using rotations, bear in mind what the dimensions of the texture would need to be to accommodate the patch once it has been rotated. Now look at the patch block. As you can see, you begin with the rotate keyword, followed by an angle. As of writing this, ZDoom only supports rotations in angles of 90, limiting your options to 90, 180, and 270. Either way, you now have a horizontal door track!


Now I'll show you how to use different rendering methods. First, here are the rendering styles you may use. All of these use the Alpha parameter to control the intensity of the effect chosen.
  • Copy - The patch is completely solid. No translucency or other effects are applied. This is the default and you don't need to apply it.
  • CopyAlpha - Copy for PNGs with their own translucency.
  • Translucent - Basic translucency.
  • Add - Additive translucency, which makes the patch appear bright as if it's producing its own light.
  • Subtract - Removes the patch from the patches beneath it while inverting the patch.
  • ReverseSubtract - The same as subtract, but without inversion.
  • Modulate - Darkens the patch considerably.
IMPORTANT! A common misconception is that translucency affects the final texture. Keep in mind when using translucency that you cannot make the resulting texture translucent, only the patches in relation to one another. As such, using translucency on a single-patch texture will result in a darkened mess. Consider the texture itself to be a black canvas. When you place a patch on it and make it translucent, in game on a wall or HUDMessage, you will see the "canvas" behind the patch.
Let's create another texture with two distinct patches; a wooden crate with a label on it.

texture WOOD10, 128, 128
{
   Patch RW13_1, 0, 0 //first, the base texture
   Patch PS18A0, 34, 43 //our label, a radiation sign from Doom 2. Its offset places it roughly in the center
   {
      Style Translucent
      Alpha 0.6
   }
}

Now if you load your TEXTURES lump with Doom 2, wherever you see a big wooden crate, it will have a translucent radiation sign on it. The other rendering modes are just as easy to use. With the exception of Blend and Translation together, you can freely combine any styles and alterations you wish.


Next, I'll show you how to make a scaled texture. Let's say you've got an image that's 256x256, and want it to be only 128x128 in-game. That's easy to do.

texture SCALED, 256, 256
{
   XScale 2
   YScale 2

   Patch SCALE_ME, 0, 0
}

As you can see, it's as simple as scaling it down by two. If you wanted it to fit to a 64x64 texture for use as a flat, you would scale by four and so on.
IMPORTANT! When defining a scaled texture, make sure you set the image's dimensions as the size of the texture, and not the size you want to scale down to!TEXTURES' scaling is quite robust. Let's take an image with far more oddball dimensions and scale it down. For instance, I have a texture that is 419x531, and I want to scale it down to 80x128. Open a calculator program and enter in the width of your texture. Divide this by the desired width, and the output number is your scaling factor.

texture SCALED, 419, 532
{
   XScale 5.2375
   YScale 4.15625

   Patch SCALE_ME, 0, 0
}

As you can see, the scaling factor can be decimalized, allowing for greater flexibility. You can also scale images up. Here's a texture that's 64x64, scaled up to 128x128.

texture SCALED, 64, 64
{
   XScale 0.5
   YScale 0.5

   Patch SCALE_ME, 0, 0
}

The process to get an inverted scaling factor is more or less the same. Take the dimensions you want, and divide them into the dimensions of the image.


Finally, TEXTURES can be used to create sprites. The process is much the same as creating a new texture, with an extra set of parameters. Let's create a simple flipped decoration.

sprite FCAND0, 37, 53
{
   Offset 19, 49

   Patch FCANA0, 0, 0
   {
      FlipX
   }
}

This code will give us a flaming can that's been flipped on its X axis. You could go on to redefine the other two frames of it in this manner to create a mirrored flaming can decoration. Note the offset keyword before the patch block. This tells the engine where to draw the sprite in relation to its physical location. Here, I'm using the offsets of the FCANA0 sprite.

You can also make new weapon sprites in a similar way. For example, here's the player's fist on the left side of the screen, again using a simple FlipX command.

sprite PUNGE0, 113, 42
{
   Offset -151, -126

   Patch PUNGA0, 0, 0
   {
      FlipX
   }
}

Note that when using the Scale functions for sprites, offsets can become difficult to calculate. While scaling can be directly applied to any actor from within DECORATE or through ACS, high-resolution weapon sprites require scaling via TEXTURES. Unfortunately, I have no easy method for calculating these offsets except by trial and error.
A note on sprite naming: When using the sprite frames [, \, and ], you must enclose the name in quotations or the parser will not recognize it! For example, "POSS\1".Now that you understand TEXTURES, you may wonder why you should use it. If you don't require anything more advanced than a list of textures you can use, TEXTURES is really not necessary. However, with it you can accomplish a number of things and save a considerable amount of space. A number of texture packs offer recolored versions of many classic Doom textures, but you can do these with translation code now to save space. You can use flipped and rotated versions of classic textures without having to add anything new, complete textures that require mirroring (for instance, from games like Doom 64, Duke Nukem 3D and Blood), and any number of other graphic-related needs.

Log in to comment

Archive

What's old?

Submit News

Submit News

Donate and Help keeping the Realm667 alive!