1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- Created by texi2html 1.64 -->
<!--
Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author)
Karl Berry <karl@freefriends.org>
Olaf Bachmann <obachman@mathematik.uni-kl.de>
and many others.
Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>
Send bugs and suggestions to <texi2html@mathematik.uni-kl.de>
-->
<HTML>
<HEAD>
<TITLE>Crystal Space: ProcTextures</TITLE>
<META NAME="description" CONTENT="Crystal Space: ProcTextures">
<META NAME="keywords" CONTENT="Crystal Space: ProcTextures">
<META NAME="resource-type" CONTENT="document">
<META NAME="distribution" CONTENT="global">
<META NAME="Generator" CONTENT="texi2html 1.64">
</HEAD>
<BODY LANG="" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<A NAME="SEC344"></A>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_164.html#SEC343"> < </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_166.html#SEC350"> > </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_161.html#SEC340"> << </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_164.html#SEC343"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_166.html#SEC350"> >> </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="index.html#SEC_Top">Top</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_toc.html#SEC_Contents">Contents</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_285.html#SEC711">Index</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_abt.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<HR SIZE=1>
<H3> 7.3.1 Procedural Texture System </H3>
<!--docid::SEC344::-->
<P>
<EM>Written by Samuel Humphreys, <A HREF="mailto:samuel@users.sourceforge.net">samuel@users.sourceforge.net</A>.</EM>
</P><P>
At the time of this writing procedural texture support is available with the
following configurations:
</P><P>
<UL>
<LI>
In 8, 15, 16, and 32-bit software renderer on all platforms.
<P>
<LI>
In OpenGL on platforms which support OpenGL. Currently there is a hardware
backbuffer implementation and a 16/32-bit software implementation. (The
16-bit implementation works with OpenGL 1.2, only.)
<P>
<LI>
DirectX support has yet to be added.
</UL>
<P>
<A NAME="SEC345"></A>
<H4> Creating and Using a Procedural Texture </H4>
<!--docid::SEC345::-->
<P>
Here is the basic, minimum code required to render text onto a procedural
texture.
</P><P>
<TABLE><tr><td> </td><td class=example><pre>// 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);
}
</pre></td></tr></table></P><P>
<EM>Note</EM>: 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 `<SAMP>csRect</SAMP>'
and pass it to <CODE>Print(csRect*)</CODE>.
</P><P>
The main design goal of the procedural texture subsystem is that you should be
able to treat the `<SAMP>iGraphics3D</SAMP>' pointer the same as you would an
`<SAMP>iGraphics3D</SAMP>' 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.
</P><P>
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 `<SAMP>dtsimple</SAMP>' 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.
</P><P>
<A NAME="SEC346"></A>
<H4> Considerations Before Creating a Procedural Texture </H4>
<!--docid::SEC346::-->
<P>
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.
</P><P>
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.
</P><P>
The `<SAMP>dtsimple</SAMP>' 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.
</P><P>
<A NAME="SEC347"></A>
<H4> Considerations When Creating a Procedural Texture </H4>
<!--docid::SEC347::-->
<P>
The questions you need to ask yourself at this stage in order to set the right
flags are:
</P><P>
<OL>
<LI>
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?
<P>
Flag: <CODE>CS_TEXTURE_PROC_ALONE_HINT</CODE>
</P><P>
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.
</P><P>
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).
</P><P>
<UL>
<LI>
Software Specific Details
<P>
The first distinction to draw when dealing with procedural textures in Crystal
Space is whether or not the texture manager is going to be shared with the
main renderer. If you are running at a screen depth of bigger than 8-bit it
is better for the software procedural textures to have their own texture
manager.
</P><P>
The reason for this is that the software texture manager's native format is
really 8-bit. When a true colour image is registered and prepared with the
software texture manager, a texture specific 256 colour palette is calculated
and the image converted to utilize this palette. When the software renderer
is in 15/16/32 bit modes it is only the final framebuffer writing stage which
has anything to do with these true colour pixel formats, and only in the sense
the palette points to 15/16/32 bit colours.
</P><P>
The implication for this is that if the procedural textures have their own
texture manager they can render at 8-bit and utilize a fully 8-bit texture
manager. This means that the 8-bit frame buffer can directly update the
textures image without any conversions or palette recalculations. However
this adds the restriction that you cannot use the texture handles received
from registering images with the procedural textures' texture manager with the
main renderer as its texture manager would know nothing about them.
</P><P>
To overcome this and the number of texture images you wish to use with both
texture managers is small, then just re-register the images with the main
texture manager and be careful to use the right texture handle with the
correct texture manager. Unfortunately if you wish to use the engine, for
example, to render to both textures and the engine will use the same texture
handles on both textures, you will have to share the texture manager between
the procedural texture renderers and the main screen renderer.
</P><P>
This is quite a performance hit if the screen depth is deeper than 8-bit. In
these circumstances the procedural textures buffer will have the same depth as
the screen's because the texture manager has set the palette to point at
colours at screen depth. Once it is written to, a new palette will have to be
calculated and the buffer re-converted to 8-bit.
</P><P>
Note that it is quite workable to have procedural textures bearing this flag
co-existing with other procedural textures which do not. Bear in mind,
however, that texture handles can only be used with the texture manager with
which they were registered so you can not use the same texture handle with
procedural textures which differ in this flag setting.
</P><P>
For these reasons it is necessary to be careful with which texture manager you
are dealing with, as noted above.
</P><P>
<LI>
OpenGL Specific Details
<P>
With the back buffer implementation, this flag has no effect as it always
utilizes the same texture manager as the main renderer. With the software
implementation, this flag has the same effect as with the pure software
version, as detailed above.
</UL>
<P>
<LI>
Do I require the procedural texture buffer to be persistent between frames?
<P>
Flag: <CODE>CS_TEXTURE_PROC_PERSISTENT</CODE>
</P><P>
If you only want to redraw part of the texture, you can normally pass the
desired rectangle to the <CODE>Print()</CODE> 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 <CODE>Print()</CODE>.
</P><P>
<UL>
<LI>
Software Specific Details
<P>
This flag has no effect for the software drivers as the buffer is always
persistent.
</P><P>
<LI>
OpenGL Specific Details
<P>
With the hardware backbuffer implementation, the image you render to the
backbuffer is of course overwritten by the main renderer. If you set this
flag then the backbuffer drivers will rewrite the texture to the backbuffer
when you call BeginDraw so you can carry on working as usual as if it was
always there.
</UL>
<P>
<LI>
Do I require mip-mapping?
<P>
Flag: <CODE>CS_TEXTURE_NOMIPMAPPING</CODE><BR>
Flag: <CODE>CS_TEXTURE_PROC_MIPMAP_ON_SYNC</CODE>
</P><P>
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
`<SAMP>CS_TEXTURE_NOMIPMAPPING</SAMP>'. 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 <CODE>iTexturehandle->ProcTextureSync()</CODE>.
If none of these flags is specified, mipmapping is done automatically.
</P><P>
<LI>
What about visibility considerations?
<P>
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 `<SAMP>dtsimple</SAMP>' 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.
</OL>
<P>
<A NAME="SEC348"></A>
<H4> Considerations When Using a Procedural Texture </H4>
<!--docid::SEC348::-->
<P>
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 <CODE>iGraphics3D->Print(csRect*)</CODE> ability to just
update a small portion of the buffer.
</P><P>
<A NAME="SEC349"></A>
<H4> Considerations After Using a Procedural Texture </H4>
<!--docid::SEC349::-->
<P>
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
<CODE>IncRef()</CODE>.
<A NAME="Sound Drivers"></A>
<HR SIZE=1>
<TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0>
<TR><TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_164.html#SEC343"> < </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_166.html#SEC350"> > </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_161.html#SEC340"> << </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_164.html#SEC343"> Up </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_166.html#SEC350"> >> </A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT"> <TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="index.html#SEC_Top">Top</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_toc.html#SEC_Contents">Contents</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_285.html#SEC711">Index</A>]</TD>
<TD VALIGN="MIDDLE" ALIGN="LEFT">[<A HREF="cs_abt.html#SEC_About"> ? </A>]</TD>
</TR></TABLE>
<BR>
<FONT SIZE="-1">
This document was generated
using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html
"><I>texi2html</I></A>
</BODY>
</HTML>
|