/*---------------------------------------------------------------------------* Project: Dolphin/Revolution gx demo File: pix-blend.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. *---------------------------------------------------------------------------*/ #include #include "cmn-model.h" #define SCREEN_WD 1 // Dummy - actual value filled at runtime #define SCREEN_HT 1 // Dummy - actual value filled at runtime #define SCREEN_ZFAR 1.0f // far plane Z in screen coordinates #define SCREEN_ZNEAR 0.0f // near plane Z in screen coordinates #define ZBUFFER_MAX 0x00ffffff /*---------------------------------------------------------------------------* Typedefs *---------------------------------------------------------------------------*/ typedef struct { char* title; GXBlendMode type; GXBlendFactor sfactor; GXBlendFactor dfactor; GXLogicOp logic; } Blend; typedef struct { Model* model; Camera* camera; ViewPort* viewport; Blend* blend; u32 flag; } Scene; #define SCENE_DRAWN (1<<0) #define SCENE_CURSOR (1<<1) #define SCENE_LCURSOR0 (1<<2) #define SCENE_LCURSOR1 (1<<3) /*---------------------------------------------------------------------------* Forward references *---------------------------------------------------------------------------*/ void SceneDraw( Scene* ); void SceneDrawInfo( Scene* ); void SceneControl( DEMOPadStatus* ); static void PrintIntro( void ); /*---------------------------------------------------------------------------* Rendering parameters *---------------------------------------------------------------------------*/ Camera myCamera = { { 0.0f, 0.0f, 30.0f }, // position { 0.0f,1000.0f, 0.0f }, // target { 0.0f, 0.0f, 1.0f }, // upVec 33.3f, // fovy 16.0f, // near plane Z in camera coordinates 1024.0f, // far plane Z in camera coordinates }; ViewPort myViewPort[] = { // full size (these are adjusted in main) { 0, 0, SCREEN_WD*2, SCREEN_HT*2 }, // half size { 0, 0, SCREEN_WD, SCREEN_HT }, { 0, SCREEN_HT, SCREEN_WD, SCREEN_HT }, { SCREEN_WD, 0, SCREEN_WD, SCREEN_HT }, { SCREEN_WD, SCREEN_HT, SCREEN_WD, SCREEN_HT }, }; Blend myBlend[] = { { "BLEND1", GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR }, { "BLEND2", GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR }, { "BLEND3", GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR }, { "BLEND4", GX_BM_BLEND, GX_BL_DSTCLR, GX_BL_ZERO, GX_LO_CLEAR }, }; GXColor sceneBgColor = { 32, 32, 128,255}; Scene myScene[] = { { &cmModel[3], &myCamera, &myViewPort[0], &myBlend[0], 0 }, { &cmModel[3], &myCamera, &myViewPort[1], &myBlend[0], 0 }, { &cmModel[3], &myCamera, &myViewPort[2], &myBlend[1], 0 }, { &cmModel[3], &myCamera, &myViewPort[3], &myBlend[2], 0 }, { &cmModel[3], &myCamera, &myViewPort[4], &myBlend[3], 0 }, }; #define NUMSCENE (sizeof(myScene)/sizeof(Scene)) /*---------------------------------------------------------------------------* Application main loop *---------------------------------------------------------------------------*/ void main ( void ) { GXRenderModeObj *rmp; u32 i; // initialize render settings and set clear color for first frame DEMOInit( NULL ); // Defined in $(REVOLUTION_SDK_ROOT)/build/libraries/demo/src/DEMOInit.c GXInvalidateTexAll( ); GXSetCopyClear( sceneBgColor, ZBUFFER_MAX ); // Perform dummy copy operation to clear eFB by specified color GXCopyDisp( DEMOGetCurrentBuffer(), GX_TRUE ); rmp = DEMOGetRenderModeObj(); for(i = 0; i < 5; i++) { myViewPort[i].xorg *= rmp->fbWidth/2; myViewPort[i].yorg *= rmp->efbHeight/2; myViewPort[i].width *= rmp->fbWidth/2; myViewPort[i].height *= rmp->efbHeight/2; } PrintIntro(); while( ! ( DEMOPadGetButton(0) & PAD_BUTTON_MENU ) ) { // get pad status DEMOPadRead( ); // General control & model animation SceneControl( &DemoPad[0] ); cmModelAnime( &DemoPad[0], &myCamera ); // Draw scene DEMOBeforeRender( ); for ( i = 0; i < NUMSCENE; i ++ ) { SceneDraw( &myScene[i] ); } DEMODoneRender( ); } OSHalt("End of test"); } /*---------------------------------------------------------------------------* Functions *---------------------------------------------------------------------------*/ //============================================================================ // Scene //============================================================================ static char* factorName[] = { "0", "1", "Cs", "(1-Cs)", "Cd", "(1-Cd)", "As", "(1-As)", "Ad", "(1-Ad)", }; /*---------------------------------------------------------------------------* Name: SceneDrawBegin Description: Update the perspective and view matrices. Arguments: Scene* s Returns: none *---------------------------------------------------------------------------*/ void SceneDraw( Scene* s ) { Camera* c = s->camera; ViewPort* v = s->viewport; Blend* b = s->blend; float aspect = (float) (4.0 / 3.0); GXColor black = {0, 0, 0, 0}; // Check if drawn flag if ( !(s->flag & SCENE_DRAWN) ) return; // Set Perspective Viewing frustum MTXPerspective( c->projMtx, c->fovy, aspect, c->znear, c->zfar ); GXSetProjection( c->projMtx, GX_PERSPECTIVE ); // Set CameraView matrix MTXLookAt( c->viewMtx, &c->position, &c->up, &c->target ); // Set Viewport GXSetViewport( v->xorg, v->yorg, v->width, v->height, SCREEN_ZNEAR, SCREEN_ZFAR ); GXSetScissor( (u32)v->xorg, (u32)v->yorg, (u32)v->width, (u32)v->height ); // Set pixel processing mode GXSetFog( GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, black ); GXSetZMode( GX_TRUE, GX_LESS, GX_TRUE ); // Set blend GXSetBlendMode( b->type, b->sfactor, b->dfactor, b->logic ); // Draw model if ( s->model->draw ) (*s->model->draw)( c ); // draw information SceneDrawInfo( s ); return; } /*---------------------------------------------------------------------------* Name: SceneDrawInfo Description: Draw scene information Arguments: Returns: none *---------------------------------------------------------------------------*/ void SceneDrawInfo( Scene* s ) { Camera* c = s->camera; ViewPort* v = s->viewport; Blend* b = s->blend; char* title; // Get title name title = b->title; if ( GX_BL_ONE == b->sfactor ) { if ( GX_BL_ZERO == b->dfactor ) title = "OPAQUE"; if ( GX_BL_ONE == b->dfactor ) title = "ADD"; } if ( GX_BL_SRCALPHA == b->sfactor && GX_BL_INVSRCALPHA == b->dfactor ) title = "MODULATE"; if ( GX_BL_DSTCLR == b->sfactor && GX_BL_ZERO == b->dfactor ) title = "MULTIPLY"; // Draw parameters to the window DEMOInitCaption( DM_FT_OPQ, v->width, v->height ); DEMOPuts ( 10, 12, 0, title ); DEMOPrintf( 96, 12, 0, "Cs * %s\nCd * %s", factorName[b->sfactor-GX_BL_ZERO], factorName[b->dfactor-GX_BL_ZERO] ); // Draw cursor if ( s->flag & SCENE_CURSOR ) DEMOPuts( 2,12,0, "\x7f" ); if ( s->flag & SCENE_LCURSOR0 ) DEMOPuts(88,12,0, "\x7f" ); if ( s->flag & SCENE_LCURSOR1 ) DEMOPuts(88,20,0, "\x7f" ); return; } /*---------------------------------------------------------------------------* Name: SceneControl Description: user interface for parameter control Arguments: Returns: none *---------------------------------------------------------------------------*/ void SceneControl( DEMOPadStatus* pad ) { static s32 zoomMode = 0; static s32 cursor = 0; static s32 cursorL = 0; static u32 modelId = 3; s32 i; Scene* s; Blend* b; // Validate animation cmModel[modelId].flag = MODEL_REFERRED; // zoom mode if ( pad->buttonDown & PAD_BUTTON_A ) zoomMode ^= 1; if ( zoomMode ) { // // *** zoom mode // // show specified scene in full screen s = &myScene[cursor+1]; b = s->blend; myScene[0].blend = b; myScene[0].flag = SCENE_DRAWN; // turn off another window for ( i = 1; i < NUMSCENE; i ++ ) { myScene[i].flag = 0; } // choose a parameter if ( pad->dirsNew & DEMO_STICK_UP ) cursorL = 0; // cursor up if ( pad->dirsNew & DEMO_STICK_DOWN ) cursorL = 1; // cursor down // set cursor position myScene[0].flag |= (SCENE_LCURSOR0 << cursorL); // change blend parameter if ( pad->dirsNew & DEMO_STICK_LEFT ){ if ( cursorL == 0 ){ // Change sfactor, sfactor skips SRCCLR and INVSRCCLR if ( b->sfactor == GX_BL_INVSRCCLR+1 ) b->sfactor -= 3; else if ( b->sfactor > GX_BL_ZERO ) b->sfactor --; } else { // Change dfactor, dfactor skips DSTCLR and INVDSTCLR if ( b->dfactor == GX_BL_INVDSTCLR+1 ) b->dfactor -= 3; else if ( b->dfactor > GX_BL_ZERO ) b->dfactor --; } } if ( pad->dirsNew & DEMO_STICK_RIGHT ) { if ( cursorL == 0 ) { // Change sfactor, sfactor skips SRCCLR and INVSRCCLR if ( b->sfactor == GX_BL_SRCCLR-1 ) b->sfactor += 3; else if ( b->sfactor < GX_BL_INVDSTALPHA ) b->sfactor ++; } else { // Change dfactor, dfactor skips DSTCLR,INVDSTCLR and SRCASAT if ( b->dfactor == GX_BL_DSTCLR-1 ) b->dfactor += 3; else if ( b->dfactor < GX_BL_INVDSTALPHA ) b->dfactor ++; } } } else { // // *** catalog mode // // choose a scene. if ( pad->dirsNew & DEMO_STICK_LEFT ) cursor &= ~2; // left if ( pad->dirsNew & DEMO_STICK_RIGHT ) cursor |= 2; // right if ( pad->dirsNew & DEMO_STICK_UP ) cursor &= ~1; // up if ( pad->dirsNew & DEMO_STICK_DOWN ) cursor |= 1; // down // show 4 small windows for ( i = 1; i < 5; i ++ ) { myScene[i].flag = SCENE_DRAWN; } // turn off large window myScene[0].flag = 0; // set cursor s = &myScene[cursor+1]; s->flag |= SCENE_CURSOR; } return; } /*---------------------------------------------------------------------------* Name: PrintIntro Description: Prints the directions on how to use this demo. Arguments: none Returns: none *---------------------------------------------------------------------------*/ static void PrintIntro( void ) { OSReport("\n\n"); OSReport("************************************************\n"); OSReport("pix-blend: blend mode test\n"); OSReport("************************************************\n"); OSReport("to quit hit the menu button\n"); OSReport("\n"); OSReport(" Stick X/Y : move the cursor, change options\n"); OSReport(" A button : toggle zoom mode\n"); OSReport("************************************************\n\n"); } /*======== End of pix-blend.c ========*/