[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

7.3.1 Procedural Texture System

Written by Samuel Humphreys, samuel@users.sourceforge.net.

At the time of this writing procedural texture support is available with the following configurations:

Creating and Using a Procedural Texture

Here is the basic, minimum code required to render text onto a procedural texture.

 
// Initialize a procedural texture of dimension 128x128.
// Presuming you have already decided on which flags to use.
iImage* proc_image = (iImage*)new csImageMemory(128,128);
int flags = CS_TEXTURE_PROC | proc_tex_flags;
iTextureHandle* proc_tex =
  main_txtmgr->RegisterTexture(proc_image,flags);
main_txtmgr->PrepareTexture(proc_tex);

// Get the interface to the procedural texture buffer.
iGraphics3D* proc_G3D = proc_tex->GetProcTextureInterface();
int colour = proc_G3D->GetTextureManager()->FindRGB(255,255,255);

// Before rendering with the main renderer, render to the
// procedural texture buffer in the usual fashion.
if (proc_G3D->BeginDraw(CSDRAW_2DGRAPHICS | CSDRAW_CLEARSCREEN))
{
   proc_G3D->GetDriver2D()->Write(
     10, 10, colour, -1, "procedural texture");
   proc_G3D->FinishDraw();
   proc_G3D->Print(NULL);
}

Note: It would be better not to clear the screen each time and it would be also better to calculate the extents of the text message as a `csRect' and pass it to Print(csRect*).

The main design goal of the procedural texture subsystem is that you should be able to treat the `iGraphics3D' pointer the same as you would an `iGraphics3D' pointer to the main renderer. The mucky details of its implementation only surfaces to the application programmer when setting the flags while registering the procedural texture. Almost everything else is taken care of transparently.

The only blemish on an otherwise consistent interface and behavious across all platforms and implementations is to do with the texture manager. This arises because there is a too good an optimisation to lose with the software drivers, which requires a little care from the app programmer. It is basically this: When you query for the texture manager from the procedural texture buffer interface it may or may not be the same texture manager as that which is used by the main renderer. So you need to test for this and act accordingly. See the example application `dtsimple' for an example of how to deal with this. More details on this quirk are found below. The rest of this document is really about the choice of flags, and to be able to choose the right flags it is necessary to know something about how it all works.

Considerations Before Creating a Procedural Texture

First a warning: Procedural textures are quite expensive to utilize so if they are to be used at all, use them sparingly. Drawing on a procedural texture is in the best case as slow as drawing on screen. Depending on the special features you request for this texture via flags, things can even be worse.

For the most part procedural textures are useful if you intend for the texture images' content to respond to the user and where it would be impossible or too expensive to precompute all possible outcomes.

The `dtsimple' test application demonstrates in more detail how to setup and use procedural textures in ways which I wouldn't recommended for the normal application. The procedural textures it uses are all quite expensive and are really done that way to test the code. It is not recommended to have the engine render to a procedural texture unless thats absolutely what you need to do.

Considerations When Creating a Procedural Texture

The questions you need to ask yourself at this stage in order to set the right flags are:

  1. Do I wish to render textures on to my procedural texture? If so do I want to use these textures to render on the main screen also?

    Flag: CS_TEXTURE_PROC_ALONE_HINT

    If you can get away with having a set of textures devoted specifically to the procedural texture subsystem or none at all this is a big performance bonus on some configurations, while incurring no performance penalty on others. So I would strongly recommend setting this flag under these circumstances.

    When using this flag, the texture manager used by the procedural texture may or may not be different from the main texture manager. So you have to test for this. Without this flag, they are always the same (but this may be a major performance hit).

  2. Do I require the procedural texture buffer to be persistent between frames?

    Flag: CS_TEXTURE_PROC_PERSISTENT

    If you only want to redraw part of the texture, you can normally pass the desired rectangle to the Print() function. However, if the area you want to redraw is not rectangular, for example if you want to write some text over the existing texture, you have to use this flag. This will guarantee that whatever you draw on the texture, it will still be there when you start to draw on the texture again. In the example you would use this flag, then draw the text on the existing texture and, if possible, pass a rectangle that fits the size of the text to Print().

  3. Do I require mip-mapping?

    Flag: CS_TEXTURE_NOMIPMAPPING
    Flag: CS_TEXTURE_PROC_MIPMAP_ON_SYNC

    Naturally, it would be better if you did not specify mip-mapping, as this would be very expensive to do each time you update the procedural texture, so if you can possibly avoid it, do so by specifying `CS_TEXTURE_NOMIPMAPPING'. Otherwise the next best approach is to specify it to mip map on sync. This means that mipmaps won't be calculated automatically, but you must tell the texture to do this. You can command to refresh mip mapping with the method iTexturehandle->ProcTextureSync(). If none of these flags is specified, mipmapping is done automatically.

  4. What about visibility considerations?

    Hopefully this issue should not arise, because it would be unwise to refresh procedural textures each frame automatically when the texture is not visible (Although `dtsimple' pretty much does so.) Also the procedural textures are all implemented at the graphics driver level and the engine (which has all the visibility determination code) doesn't know anything about procedural textures, so if you did require to determine visiblility before refreshing then currently you would have to implement your own little visibility test. Unless there is a huge demand or a really compelling reason to change the current situation, I don't expect this to change.

Considerations When Using a Procedural Texture

The biggest thing to definitely do when rendering to procedural textures is to do it before you render to the main screen. This is because with OpenGL and the procedural texture buffer may be the backbuffer. Lastly, of course, try and utilize the iGraphics3D->Print(csRect*) ability to just update a small portion of the buffer.

Considerations After Using a Procedural Texture

Nothing particularly special needs to be done. Destroy the texture handle as you would an ordinary texture. The only thing to bear in mind is that the interfaces to the buffers are destroyed also, so if for some reason you absolutely need to hang on to them for a while you just need to call IncRef().


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html