Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > c1088eb1b876a17e9a504ed383d0626b > files > 543

ClanLib-devel-2.1.2-2.fc15.i686.rpm

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Raster Graphics - ClanLib SDK</title>
<link rel="stylesheet" media="screen" type="text/css" href="clanlib.css"/>
<link rel="icon" href="gfx/favicon.png" type="image/png"/>
</head>
<body>
<div id="content">
<h1><a href="."><img src="gfx/clanlib.png" alt="ClanLib SDK" /></a></h1>
<!--
<div style="float: right;">
<a href="download.html">Download</a> :
<a href="docs.html">Documentation</a> :
<a href="development.html">Development</a> :
<a href="donations.html">Donations</a> :
<a href="http://www.rtsoft.com/clanlib">Forum</a> :
<a href="contributions.html">Contributions</a>
</div>
-->
<h2>
<img src="gfx/overview.png"/>Raster Graphics
</h2>

<p>Raster graphics in ClanLib are managed by four types of objects:</p>

<ul>
<li>Pixel buffers</li>
<li>Image providers</li>
<li>Texture objects</li>
<li>Sprites</li>
</ul>

<h3>Pixel Buffers</h3>

<p>A pixel buffer, managed by <span class="code">CL_PixelBuffer</span>, is a
container object for a raster image stored in system memory.  A pixel buffer
consists of a pixel format description (<span
class="code">CL_PixelFormat</span>) and then a pointer to the memory in
which the image is stored.</p>

<p>The following example creates a pixel buffer and fills it with a raster
image that looks like a gradient shade from red to blue:</p>

<pre>
CL_PixelBuffer create_gradient_image()
{
	CL_PixelBuffer buffer(256, 256, 256*4, CL_PixelFormat::rgba8888);
	unsigned int *pixel_data = (unsigned int *) buffer.get_data();
	for (int y = 0; y < 256; y++)
	{
		for (int x = 0; x < 256; x++)
		{
			unsigned int red = 255-x;
			unsigned int green = 0;
			unsigned int blue = x;
			unsigned int alpha = 255;
			pixel_data[x + y * 256] =
				(red << 24) + (green << 16) + (blue << 8) + alpha;
		}
	}
	return buffer;
}
</pre>

<p>To draw a pixel buffer on a graphic context, simply call <span
class="code">CL_GraphicContext::draw_pixels</span>:

<pre>
CL_DisplayWindow window(256, 256, "Raster Example");
CL_GraphicContext gc = window.get_gc();
CL_InputContext ic = window.get_ic();
CL_PixelBuffer buffer = create_gradient_image();

while (ic.get_keyboard().get_keycode(CL_KEY_ESCAPE) == false)
{
	gc.draw_pixels(0, 0, buffer);
	window.flip();
	CL_KeepAlive::process();
}
</pre>

<h3>Image Providers</h3>

<p>Image providers are classes that can load or save pixel buffers.  The
interface which all the image providers implement is called <span
class="code">CL_ImageProviderType</span>. The interface is simple:</p>

<pre>
class CL_ImageProviderType
{
public:
	//: Called to load an image with this provider type.
	virtual CL_PixelBuffer load(
		const CL_String &filename,
		CL_VirtualDirectory directory)=0;

	//: Called to save a given PixelBuffer to a file
	virtual void save(
		CL_PixelBuffer buffer,
		const CL_String &filename,
		CL_VirtualDirectory directory)=0;
};
</pre>

<p>ClanLib itself implements a few image providers for common image formats:
<span class="code">CL_PNGProvider</span>, <span
class="code">CL_JPEGProvider</span>, <span
class="code">CL_PCXProvider</span> and <span
class="code">CL_TargaProvider</span>.  Each of those providers implement
static function versions of the above functions, so to load a PNG image the
following syntax would work:</p>

<pre>
CL_PixelBuffer png_image = CL_PNGProvider::load("test.png");
</pre>

<p>If you do not know the type of the image format, or if you want to load
an image from any of the formats known by ClanLib, you can use the <span
class="code">CL_ImageProviderFactory</span> class.  All image providers in
ClanLib are registered in the factory, allowing you to load images like
this:</p>

<pre>
CL_PixelBuffer image1 = CL_ImageProviderFactory::load("test.png");
CL_PixelBuffer image2 = CL_ImageProviderFactory::load("test.jpg");
</pre>

<h3>Texture Objects</h3>

<p>Pixel buffers are images stored in system memory, in a format that can be
freely specified.  This gives certain limitations - the images can basically
only be rendered using <span
class="code">CL_GraphicContext::draw_pixels</span>.  If an image needs to be
drawn in more complex ways, it needs to be placed in a texture object.  A
texture is an image stored in video memory in a format native to the
graphics card's processing unit, and is used by texturing units or fragment
shader programs as image sources.</p>

<p>Texture objects are managed by <span class="code">CL_Texture</span> in
ClanLib. Textures have many properties that affect how a texture unit may
calculate the texels used as input for its texture functions. For example,
<span class="code">CL_Texture::set_wrap_mode</span> configures what happens
if the texel is located outside the dimensions of the texture.  If the
wrapping mode is set to <span class="code">cl_wrap_clamp_to_edge</span> it
will use the pixel at the edge, or if it is set to <span
class="code">cl_wrap_repeat</span> it will set it to tx/width, for example.</p>

<p>To load a pixel buffer into a texture, the following code could be
used:</p>

<pre>
CL_PixelBuffer buffer = create_gradient_image();
CL_Texture texture(gc, cl_texture_2d);
texture.set_image(buffer);
</pre>

<p>Modern graphics cards are very fast at rendering things, however each
time you change the state of the graphic context, such as changing the
currently set texture for a texture unit, you lose a lot of performance. It
isn't really that important what you change, the key to getting a high speed
is to set up the states, then render a lot, then change states, then render
a lot, etc.</p>

<p>Since drawing 2D usually means drawing a lot of different images, having
a seperate texture for each image will produce a large performance drop. A
solution to this problem is to store several images in the same texture,
thus avoiding you have to change the state of the graphic context between
your images drawn. <span class="code">CL_TextureGroup</span> is a class that
help you store images in the same texture:</p>

<pre>
// Load images:
CL_PixelBuffer image1 = CL_ImageProviderFactory::load("test.png");
CL_PixelBuffer image2 = CL_ImageProviderFactory::load("test.jpg");

// Create a texture of 256x256
CL_TextureGroup texture_group(CL_Size(256, 256));

// Retrieve areas in the texture for our images:
CL_Subtexture subtexture_image1 = texture_group.add(image1.get_size());
CL_Subtexture subtexture_image2 = texture_group.add(image2.get_size());

// Upload images to texture:
subtexture_image1.get_texture().set_subimage(
	subtexture_image1.get_geometry().left,
	subtexture_image1.get_geometry().top,
	image1);
subtexture_image2.get_texture().set_subimage(
	subtexture_image2.get_geometry().left,
	subtexture_image2.get_geometry().top,
	image2);
</pre>

<h3>Sprites</h3>

<p><span class="code">CL_Sprite</span> is a high-level interface that
automatically stores images in textures and supports advanced features such
as animation. For further information on sprites, see the <a
href="sprites.html">sprite overview</a>.</p>

</div>

</body>
</html>