<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://dreamcast.wiki/wiki/index.php?action=history&amp;feed=atom&amp;title=Paletted_Textures</id>
	<title>Paletted Textures - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://dreamcast.wiki/wiki/index.php?action=history&amp;feed=atom&amp;title=Paletted_Textures"/>
	<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Paletted_Textures&amp;action=history"/>
	<updated>2026-04-20T09:10:45Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://dreamcast.wiki/wiki/index.php?title=Paletted_Textures&amp;diff=2134&amp;oldid=prev</id>
		<title>Unknown user: Created page with &quot;= Specifying a palette = The PVR graphics chip has an internal bank of color palette entries. This bank contains a total of 1024 color entries, each of which is 32 bits wide (...&quot;</title>
		<link rel="alternate" type="text/html" href="https://dreamcast.wiki/wiki/index.php?title=Paletted_Textures&amp;diff=2134&amp;oldid=prev"/>
		<updated>2023-03-02T01:04:34Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Specifying a palette = The PVR graphics chip has an internal bank of color palette entries. This bank contains a total of 1024 color entries, each of which is 32 bits wide (...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Specifying a palette =&lt;br /&gt;
The PVR graphics chip has an internal bank of color palette entries. This bank contains a total of 1024 color entries, each of which is 32 bits wide (no matter what truecolor format you choose).&lt;br /&gt;
&lt;br /&gt;
The color palette can be configured in three modes which match the format of the standard 16-bit textures: ARGB1555, ARGB4444, RGB565. There&amp;#039;s also a 32-bit mode, which allows you to use ARGB8888 colour palette entries.&lt;br /&gt;
&lt;br /&gt;
The palette mode is a global setting - it affects all rendering of paletted textures. So it&amp;#039;s a good idea to set this to something that fills all your paletted texture needs.&lt;br /&gt;
&lt;br /&gt;
To set the palette format, you use the pvr_set_pal_format function, with one of the PVR_PAL_ values. For example, to set up an ARGB8888 palette:&lt;br /&gt;
  pvr_set_pal_format(PVR_PAL_ARGB8888);&lt;br /&gt;
&lt;br /&gt;
To set a colour palette entry, use the pvr_set_pal_entry function. This function takes a palette index from 0 to 1023, and a colour value. The colour value is in whatever format you set the palette to. In our case, that&amp;#039;s ARGB8888. So, to set the first four palette entries to transparent, black, white, and red, we could do something like this:&lt;br /&gt;
 #define PACK_ARGB8888(a,r,g,b) ( ((a &amp;amp; 0xFF) &amp;lt;&amp;lt; 24) | ((r &amp;amp; 0xFF) &amp;lt;&amp;lt; 16) | ((g &amp;amp; 0xFF) &amp;lt;&amp;lt; 8) | (b &amp;amp; 0xFF) )&lt;br /&gt;
 pvr_set_pal_entry(0, PACK_ARGB8888(0, 0, 0, 0));&lt;br /&gt;
 pvr_set_pal_entry(1, PACK_ARGB8888(255, 0, 0, 0));&lt;br /&gt;
 pvr_set_pal_entry(2, PACK_ARGB8888(255, 255, 255, 255));&lt;br /&gt;
 pvr_set_pal_entry(3, PACK_ARGB8888(255, 255, 0, 0));&lt;br /&gt;
&lt;br /&gt;
There are 1024 colour palette entries. If you&amp;#039;re using 4bpp images (16 colours each), you treat this as 64 separate 16 colour palettes. Palette 0 consists of colours 0 through 15, palette 1 consists of colours 16 through 31, and so on. For 8bpp images, you get four 256 colour palettes, with palette 0 being colours 0 through 255, palette 1 being colours 256 through 511, and so on.&lt;br /&gt;
&lt;br /&gt;
We&amp;#039;ll cover how to select which palette to use later. If you do not set a palette, you end up with palette 0.&lt;br /&gt;
&lt;br /&gt;
=Loading textures=&lt;br /&gt;
You can load a paletted texture in the normal way, using pvr_txr_load_ex. You just need to make sure they&amp;#039;re twiddled, which pvr_txr_load_ex will do for you.&lt;br /&gt;
&lt;br /&gt;
Actually loading texture data is a bit trickier than it could be - the utility functions in KOS to load textures automatically convert everything to 16bpp RGB565, which is obviously not what we want.&lt;br /&gt;
&lt;br /&gt;
I might post some sample code for reading a paletted image later. Most likely, either a PNG, PCX, or BMP file. But for now, just assume that you&amp;#039;ve managed to load an 8bpp image from somewhere...&lt;br /&gt;
 void *image_data;&lt;br /&gt;
 pvr_ptr_t texture_pointer;&lt;br /&gt;
 int width, height;&lt;br /&gt;
&lt;br /&gt;
To load an 8bpp image...&lt;br /&gt;
 pvr_txr_load_ex(image_data, texture_pointer, width, height, PVR_TXRLOAD_8BPP);&lt;br /&gt;
&lt;br /&gt;
To load a 4bpp image...&lt;br /&gt;
 pvr_txr_load_ex(image_data, texture_pointer, width, height, PVR_TXRLOAD_4BPP);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Using paletted textures=&lt;br /&gt;
Now that we&amp;#039;ve come this far, we get to the easy part - using the textures.&lt;br /&gt;
&lt;br /&gt;
To use a paletted texture, you just need to specify the texture format when building the polygon header. For example, for an 8-bit texture with no filtering, using the default palette, and being rendered into the punch-through display list:&lt;br /&gt;
&lt;br /&gt;
 pvr_poly_hdr_t hdr;&lt;br /&gt;
 pvr_poly_cxt_t cxt;&lt;br /&gt;
 pvr_poly_cxt_txr(&amp;amp;cxt, PVR_LIST_PT_POLY, PVR_TXRFMT_PAL8BPP, width, height, texture_pointer, PVR_FILTER_NONE);&lt;br /&gt;
 pvr_poly_compile(&amp;amp;hdr, &amp;amp;cxt);&lt;br /&gt;
&lt;br /&gt;
Same deal for 4bpp textures - just substitude PVR_TXRFMT_PAL4BPP.&lt;br /&gt;
&lt;br /&gt;
= Choosing a different palette =&lt;br /&gt;
If you want to use something other than the default palette, you need to use the PVR_TXRFMT_8BPP_PAL and PVR_TXRFMT_4BPP_PAL macros:&lt;br /&gt;
 pvr_poly_cxt_txr(&amp;amp;cxt, PVR_LIST_PT_POLY, PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_8BPP_PAL(1), width, height, texture_pointer, PVR_FILTER_NONE);&lt;br /&gt;
&lt;br /&gt;
The numbers passed to PVR_TXRFMT_xBPP_PAL are palette numbers, not indexes. So in this example, the texture will use the second 256 colour palette, consisting of palette entries 256 through 511.&lt;br /&gt;
&lt;br /&gt;
= Why bother? =&lt;br /&gt;
The main reason is memory usage. An 8bpp image takes up half as much video RAM as a 16bpp image, and a 4bpp image takes up half as much again. This is useful for 2D games, particularly if the source images use colour palettes anyway.&lt;br /&gt;
&lt;br /&gt;
You also get the ability to do palette animation, and use the same image multiple times with different colour palettes. These are tricks that a lot of old console games used to use to get animation from static images, and to provide a bit of variety to the graphics without needing to include more graphics data.&lt;br /&gt;
&lt;br /&gt;
You can also use paletted images for fonts. The ROM fonts are natively 4bpp images. Typically, we would convert them to a 16bpp ARGB4444 image, with the colour of every pixel set to white. That&amp;#039;s a huge waste of memory, when we could just load the font as a 4bpp texture. In fact, anywhere you might use an ARGB4444 texture with all the colours set to white can be replaced with a 4bpp texture.&lt;br /&gt;
&lt;br /&gt;
It&amp;#039;s also useful for simulating luminance-only and alpha-only textures. You can simulate a luminance-only (greyscale) texture by using an 8bpp image, and setting colour palette entry i to ARGB(255, i, i, i). Similarly, you can simulate an alpha-only texture by setting colour palette entry i to ARGB(i, 255, 255, 255). By itself, this isn&amp;#039;t necessarily useful, since the PVR&amp;#039;s framebuffer is only 5 or 6 bits per colour channel. However, if you combine this with blending, you can eliminate a lot of the rendering artefacts you&amp;#039;d get by using an ARGB4444 texture. For example, you might have a particle texture which is coloured by setting the vertex colours, and blended onto the scene, or a lightmap. Since the PVR renders everything internally in 32bpp, and only converts to RGB565 as the final step, rendering quality would be improved.&lt;/div&gt;</summary>
		<author><name>Unknown user</name></author>
	</entry>
</feed>