[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Crystal Space supports procedural textures. These are textures that you can change dynamically (at runtime) so that you get the appearance of an animated texture.
The current implementation of procedural textures works by rendering the contents of the texture on screen and then doing a copy to the texture memory. This means that procedural textures must be updated before the 3D view starts rendering and it also means that the 3D view must make sure that that part of the screen is changed (i.e. either put geometry there or manually clear screen every frame). Note that all textures can be updated with this technique. i.e. you don't need to mark a texture as being procedural.
The following code demonstrates how you can update a texture image:
bool UpdateTexture (iTextureWrapper* tex) { g3d->SetRenderTarget (tex->GetTextureHandle ()); if (!g3d->BeginDraw (CSDRAW_2DGRAPHICS)) return false; ... // Do various operations on g2d. ... g3d->FinishDraw (); return true; } |
Similarly, it is also possible to do 3D graphics on a procedural texture.
Note that the code above may overwrite what is currently displayed on screen! So make sure to do it before anything you need is rendered.
SetRenderTarget
also has a second parameter which is called
`persistant' and which is set to false by default. If you set this to
true then the previous contents of the texture is copied on screen first.
That means you can make modifications to an existing texture. With this
parameter set to false (default) you have to create the entire texture
again. Note that setting `persistant' to true is slower if you intend
to update the entire texture area anyway.
Another way to realize procedural textures is to use the function
iTextureHandle->Blit()
which can copy a RGBA or BGRA buffer
from memory directly to a texture. This is useful for procedural textures
where you compute the pixel data directly or obtain it from some external
source and hence don't need the 2D or 3D graphics functions.
In the `cstool' module there is a convenience class you can use
to make updating of procedural textures easier. This class is called
csProcTexture
. Basically you make a subclass of this class like this:
#include "cstool/proctex.h" class MyProcTexture : public csProcTexture { public: MyProcTexture () { } virtual ~MyProcTexture () { } virtual bool PrepareAnim (); virtual void Animate (csTicks current_time); }; bool MyProcTexture::PrepareAnim () { if (anim_prepared) return true; if (!csProcTexture::PrepareAnim ()) return false; ... // Do your stuff. return true; } void MyProcTexture::Animate (csTicks current_time) { g3d->SetRenderTarget (...); ... g3d->FinishDraw (); } |
To use this procedural texture you must do the following:
MyProcTexture* proctex = new MyProcTexture (); if (proctex->Initialize (object_reg)) { iTextureWrapper* txt = proctex->GetTextureWrapper (); iMaterialWrapper* mat = engine->CreateMaterial ("mymaterial", txt); ... } |
csProcTexture
will make sure that your Animate
routine
is called when needed. In practice this means that your animate routine
will be called AFTER the first time the texture was needed. This is
because Animate
will change the display (because procedural textures
render on screen) so it can't be done while rendering other objects. In
general this is not really a problem since typically the material will be
needed as soon as only a tiny part of the object is visible and this will
only be visible for one frame.
To minimize the impact of this effect you can make sure that the initial
contents of the procedural texture is reasonable. You can do that by
manually calling Animate
for example.
Another way to fix this is by letting your procedural texture subclass set the `always_animate' flag to true. Of course this will make things slower.
When supported by the hardware, mipmaps are generated for procedural textures.
While this improves the display quality it may have a noticeable impact on
performance. You can use the CS_TEXTURE_NOMIPMAPS
texture flag to
disable this behaviour.
iTextureHandle->Blit()
performance might differ depending on hardware
and data format. For example, NVIDIA hardware is fastest with BGRA
data but may suffer greatly when using RGBA data. On the other hand,
documentation from ATI's Software Development Kit suggests that modern
ATI hardware supports RGBA and BGRA equally well. This means
there is no "universal fastest format" for using
iTextureHandle->Blit()
, albeit for the most widespread graphics chips
BGRA seems to be the most practical choice.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] |
This document was generated using texi2html 1.76.