/*---------------------------------------------------------------------------* Project: Dolphin/Revolution gx demo File: tex-tlut32.c Copyright 1998-2006 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* tex-tlut32 Uses 2 TEV stages to emulate 32-bit palette support for CI textures *---------------------------------------------------------------------------*/ /* Explanation of the 32-bit color indexed format: The Gamecube does not have native support for 32-bit color indexed format. This is due to tradeoffs in the graphics pipeline which resulted in it being optimized for 16-bits per texture sample per read cycle. However 32-bit palettes with 8-bit index is a format which some developers find very useful. Luckily it is fairly easy to support 32-bit indexed format at the cost of using 2 TEV stages. The best way to implement 32-bit indexed format, which was suggested by Jack Mathews from Retro on the US developers gamecube.graphics newsgroup, is by splitting the 32-bit palette into two 16-bit palettes - one with the Red and Green components, the other with the Blue and Alpha components of the color, and referencing them from the same texture map in 2 TEV stages. This produces the same result as a texture with a single palette of GX_TL_RGBA8 format. A demo is provided which demonstrates a texture using a 256 entry palette. The texture is created procedurally as a set of concentric circles, and alpha-blended on top of a checkered background. The palette is set to be a smooth gradient between two RGBA values in order to demonstrate that the palette is indeed 32-bit. The palette is animated in real-time (without animating the texture pattern), by changing the endpoints of the gradient to give a color cycling effect. */ #include #include #define NUM_ENTRIES 256 #define TEX_SIZE 256 #define TEX_HALF (TEX_SIZE>>1) #define SCR_WIDTH 640 #define SCR_HEIGHT 448 static GXColor tlut32[NUM_ENTRIES] ATTRIBUTE_ALIGN(32); static u16 tlutPalette0[NUM_ENTRIES] ATTRIBUTE_ALIGN(32); static u16 tlutPalette1[NUM_ENTRIES] ATTRIBUTE_ALIGN(32); static u8 indexTexture[TEX_SIZE * TEX_SIZE] ATTRIBUTE_ALIGN(32); #define COLA 255 #define COLB 128 static u8 checkTexture[8*8] ATTRIBUTE_ALIGN(32) = { COLA, COLA, COLA, COLA, COLB, COLB, COLB, COLB, COLA, COLA, COLA, COLA, COLB, COLB, COLB, COLB, COLA, COLA, COLA, COLA, COLB, COLB, COLB, COLB, COLA, COLA, COLA, COLA, COLB, COLB, COLB, COLB, COLB, COLB, COLB, COLB, COLA, COLA, COLA, COLA, COLB, COLB, COLB, COLB, COLA, COLA, COLA, COLA, COLB, COLB, COLB, COLB, COLA, COLA, COLA, COLA, COLB, COLB, COLB, COLB, COLA, COLA, COLA, COLA, }; static GXTexObj texObj1, texObj0, texObjCheck; static GXTlutObj tlutObj0, tlutObj1; void CreatePalettes(); void CreateTexture(); void SetCITEVMode(); void SetUpRegisters(); void DrawTick(); static f32 rR0, rG0, rB0, rA0; static f32 rR1, rG1, rB1, rA1; void CreateTexture() { s32 nX, nY; s32 nI; f32 rDist; // Make a test pattern for(nY=0; nY aaaaaaccdddbbeee (TEXTURE SWIZZLE) nI = ((nY<<8)&0xfc00) + ((nX<<2)&0x3e0) + ((nY<<3)&0x18) + (nX&0x7); rDist = 1.4f*(f32)sqrt(((TEX_HALF-nX)*(TEX_HALF-nX))+((TEX_HALF-nY)*(TEX_HALF-nY))); indexTexture[nI] = (u8)(rDist); } } DCFlushRange(indexTexture, TEX_SIZE * TEX_SIZE); } void CreatePalettes() { s32 nI; for(nI=0; nI>1, // f32 top -(SCR_HEIGHT>>1), // f32 bottom -(SCR_WIDTH>>1), // f32 left SCR_WIDTH>>1, // f32 right 1, // f32 near 1000); // f32 far GXSetProjection(mProjection, // Mtx44 matrix GX_ORTHOGRAPHIC); // GXProjectionType type } // set up Camera { Mtx mView; Vec vCamPos = { 0, 0, -300 }; Vec vCamUp = { 0, 1, 0 }; Vec vCamTarget = { 0, 0, 0 }; MTXLookAt(mView, // Mtx mView &vCamPos, // Point3dPtr camPos &vCamUp, // VecPtr camUp &vCamTarget); // Point3dPtr target GXLoadPosMtxImm(mView, // Mtx mView GX_PNMTX0); // u32 id } // set up vertex attributes { GXClearVtxDesc(); // Set Position Params GXSetVtxAttrFmt(GX_VTXFMT0, // GXVtxFmt vtxfmt GX_VA_POS, // GXAttr attr GX_POS_XY, // GXCompCnt component GX_F32, // GXCompType type 0); // u8 frac GXSetVtxDesc(GX_VA_POS, // GXAttr attr GX_DIRECT); // GXAttrType type // Set Tex Coord Params GXSetVtxAttrFmt(GX_VTXFMT0, // GXVtxFmt vtxfmt GX_VA_TEX0, // GXAttr attr GX_TEX_ST, // GXCompCnt component GX_F32, // GXCompType type 0); // u8 frac GXSetVtxDesc(GX_VA_TEX0, // GXAttr attr GX_DIRECT); // GXAttrType type GXSetNumTexGens(1); // u8 nTexGens GXSetNumChans(0); // u8 nChans } } void DrawTick() { // render background checker pattern GXSetNumTevStages(1); GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP2, GX_COLOR_NULL); // Turn off alpha blending GXSetBlendMode(GX_BM_NONE, // GXBlendMode type GX_BL_ONE, // GXBlendFactor src_factor GX_BL_ZERO, // GXBlendFactor dst_factor GX_LO_CLEAR); // GXLogicOp op GXBegin(GX_QUADS, GX_VTXFMT0, 4); { GXPosition2f32( -320, 224 ); GXTexCoord2f32( 0, 14 ); GXPosition2f32( -320, -224 ); GXTexCoord2f32( 0, 0 ); GXPosition2f32( 320, -224 ); GXTexCoord2f32( 20, 0 ); GXPosition2f32( 320, 224 ); GXTexCoord2f32( 20, 14 ); } GXEnd(); // set up for 32-bit CI texture render SetCITEVMode(); // Turn on alpha blending GXSetBlendMode(GX_BM_BLEND, // GXBlendMode type GX_BL_SRCALPHA, // GXBlendFactor src_factor GX_BL_INVSRCALPHA, // GXBlendFactor dst_factor GX_LO_CLEAR); // GXLogicOp op // render a quad { f32 rRectHalfWidth; f32 rRectHalfHeight; rRectHalfWidth = TEX_SIZE; rRectHalfHeight = TEX_SIZE * 0.5f; GXBegin(GX_QUADS, GX_VTXFMT0, 4); { GXPosition2f32( -rRectHalfWidth, rRectHalfHeight ); GXTexCoord2f32( 0, 1 ); GXPosition2f32( -rRectHalfWidth, -rRectHalfHeight ); GXTexCoord2f32( 0, 0 ); GXPosition2f32( rRectHalfWidth, -rRectHalfHeight ); GXTexCoord2f32( 1, 0 ); GXPosition2f32( rRectHalfWidth, rRectHalfHeight ); GXTexCoord2f32( 1, 1 ); } GXEnd(); } } void main() { s32 nT=0; DEMOInit(NULL); OSReport("\n\n"); OSReport("**********************************************\n"); OSReport("tex-tlut32: 32-bit color indexed texture demo\n"); OSReport("**********************************************\n"); OSReport("To quit hit the start button.\n"); OSReport("\n"); OSReport("This demo has no other controls.\n"); OSReport("Refer to the source code for more information.\n"); OSReport("**********************************************\n"); OSReport("\n\n"); CreateTexture(); GXSetDispCopyGamma( GX_GM_1_0 ); SetUpRegisters(); DEMOPadRead(); // Read the joystick for this frame // While the quit button is not pressed while (!(DEMOPadGetButton(0) & PAD_BUTTON_MENU)) { // A bit of good old color cycling nT++; rR0 = 127.5f * (1.0f + (f32)sin(nT*0.210)); rG0 = 127.5f * (1.0f + (f32)sin(nT*0.152)); rB0 = 127.5f * (1.0f + (f32)sin(nT*0.085)); rA0 = 127.5f * (1.0f + (f32)sin(nT*0.119)); rA1 = 127.5f * (1.0f + (f32)cos(nT*0.179)); rR1 = 255.0f - rR0; rG1 = 255.0f - rG0; rB1 = 255.0f - rB0; CreatePalettes(); DEMOPadRead(); // Read the joystick for this frame DEMOBeforeRender(); DrawTick(); // Draw the model. DEMODoneRender(); } OSHalt("End of demo"); }