[NEW] Added 4 blending modes: Additive, Alpha Light, Multiply and Invert Color. For best results, use alpha-less black/white textures.

[CHG] Improved stability when closing a GRRLIB application.
This commit is contained in:
Xane 2009-03-10 21:27:42 +00:00
parent 9608deb240
commit 4ebd507bd5
2 changed files with 28 additions and 54 deletions

View file

@ -56,52 +56,18 @@ inline void GRRLIB_SetBlend( unsigned char blendmode ) {
case GRRLIB_BLEND_ALPHA: case GRRLIB_BLEND_ALPHA:
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
break; break;
case GRRLIB_BLEND_ADD: // Some ugly lines around the drawn texture, needs to be fixed somehow. case GRRLIB_BLEND_ADD:
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_CLEAR); GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_DSTALPHA, GX_LO_CLEAR);
break; break;
case GRRLIB_BLEND_SUB: // Doesn't work really :/ case GRRLIB_BLEND_LIGHT:
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCCLR, GX_BL_DSTALPHA, GX_LO_CLEAR);
break;
case GRRLIB_BLEND_MULTI:
GX_SetBlendMode(GX_BM_SUBSTRACT, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GX_SetBlendMode(GX_BM_SUBSTRACT, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
break; break;
case GRRLIB_BLEND_INV: // Wrong alpha information.. need to be inverted. case GRRLIB_BLEND_INV:
GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_EQUIV); case 8: GX_SetBlendMode(GX_BM_BLEND, GX_BL_INVSRCCLR, GX_BL_INVSRCCLR, GX_LO_CLEAR); break;
break; break;
case 4: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_EQUIV); break;
case 5: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_SRCALPHA, GX_LO_EQUIV); break;
case 6: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_EQUIV); break;
case 7: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_DSTALPHA, GX_LO_EQUIV); break;
case 8: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_INVDSTALPHA, GX_LO_EQUIV); break;
case 9: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_INVSRCALPHA, GX_LO_CLEAR, GX_LO_EQUIV); break;
case 10: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_INVSRCALPHA, GX_BL_SRCALPHA, GX_LO_EQUIV); break;
case 11: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_INVSRCALPHA, GX_BL_INVSRCALPHA, GX_LO_EQUIV); break;
case 12: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_INVSRCALPHA, GX_BL_DSTALPHA, GX_LO_EQUIV); break;
case 13: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_INVSRCALPHA, GX_BL_INVDSTALPHA, GX_LO_EQUIV); break;
case 14: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_DSTALPHA, GX_LO_CLEAR, GX_LO_EQUIV); break;
case 15: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_DSTALPHA, GX_BL_SRCALPHA, GX_LO_EQUIV); break;
case 16: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_DSTALPHA, GX_BL_INVSRCALPHA, GX_LO_EQUIV); break;
case 17: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_DSTALPHA, GX_BL_DSTALPHA, GX_LO_EQUIV); break;
case 18: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_DSTALPHA, GX_BL_INVDSTALPHA, GX_LO_EQUIV); break;
case 19: GX_SetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY); break;
/* Just for testing purpose, uncomment to use it.
Inverting seems to work with 13, it just uses the wrong alpha information. :/
case 4: GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_CLEAR); break;
case 5: GX_SetBlendMode(GX_BM_SUBSTRACT, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_CLEAR); break;
case 6: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_CLEAR); break;
case 7: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_AND); break;
case 8: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_REVAND); break;
case 9: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_INVAND); break;
case 10: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_XOR); break;
case 11: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_OR); break;
case 12: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_NOR); break;
case 13: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_EQUIV); break;
case 14: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_INV); break;
case 15: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_REVOR); break;
case 16: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_INVCOPY); break;
case 17: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_INVOR); break;
case 18: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_NAND); break;
case 19: GX_SetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_LO_CLEAR, GX_LO_SET); break;
*/
} }
} }
@ -557,6 +523,7 @@ inline void GRRLIB_DrawImg(f32 xpos, f32 ypos, struct GRRLIB_texImg *tex, float
if (GRRLIB_Settings.antialias == false) { if (GRRLIB_Settings.antialias == false) {
GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1); GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
} }
GX_LoadTexObj(&texObj, GX_TEXMAP0); GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
@ -613,8 +580,8 @@ inline void GRRLIB_DrawImgQuad(Vector pos[4], struct GRRLIB_texImg *tex, u32 col
if (GRRLIB_Settings.antialias == false) { if (GRRLIB_Settings.antialias == false) {
GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1); GX_InitTexObjLOD(&texObj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
} }
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_LoadTexObj(&texObj, GX_TEXMAP0);
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
@ -664,7 +631,7 @@ inline void GRRLIB_DrawImgQuad(Vector pos[4], struct GRRLIB_texImg *tex, u32 col
inline void GRRLIB_DrawTile(f32 xpos, f32 ypos, struct GRRLIB_texImg *tex, float degrees, float scaleX, f32 scaleY, u32 color, int frame) { inline void GRRLIB_DrawTile(f32 xpos, f32 ypos, struct GRRLIB_texImg *tex, float degrees, float scaleX, f32 scaleY, u32 color, int frame) {
if (tex == NULL) { return; } if (tex == NULL) { return; }
if (tex->data == NULL) { return; } if (tex->data == NULL) { return; }
if (tex->frame > (tex->nbtilew+tex->nbtileh)) { return; } if (frame > (tex->nbtilew+tex->nbtileh+tex->tilestart)) { return; }
GXTexObj texObj; GXTexObj texObj;
f32 width, height; f32 width, height;
@ -1157,14 +1124,16 @@ void GRRLIB_Init() {
GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter); GX_SetCopyFilter(rmode->aa, rmode->sample_pattern, GX_TRUE, rmode->vfilter);
GX_SetFieldMode(rmode->field_rendering, ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); GX_SetFieldMode(rmode->field_rendering, ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
if (rmode->aa) if (rmode->aa) {
// Set 16 bit RGB565
GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR); GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR);
else } else {
// Set 24 bit Z24
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
}
GX_SetDispCopyGamma(GX_GM_1_0); GX_SetDispCopyGamma(GX_GM_1_0);
// Setup the vertex descriptor // Setup the vertex descriptor
// Tells the flipper to expect direct data // Tells the flipper to expect direct data
GX_ClearVtxDesc(); GX_ClearVtxDesc();
@ -1175,7 +1144,6 @@ void GRRLIB_Init() {
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
@ -1197,18 +1165,22 @@ void GRRLIB_Init() {
GX_SetViewport(0, 0, rmode->fbWidth, rmode->efbHeight, 0, 1); GX_SetViewport(0, 0, rmode->fbWidth, rmode->efbHeight, 0, 1);
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GX_SetAlphaUpdate(GX_TRUE); GX_SetAlphaUpdate(GX_TRUE);
GX_SetAlphaCompare(GX_GREATER, 0, GX_AOP_AND, GX_ALWAYS, 0);
GX_SetColorUpdate(GX_ENABLE);
GX_SetCullMode(GX_CULL_NONE); GX_SetCullMode(GX_CULL_NONE);
VIDEO_SetBlack(false); VIDEO_SetBlack(false);
// Default settings // Default settings
GRRLIB_Settings.antialias = true; GRRLIB_Settings.antialias = true;
GRRLIB_Settings.blend = GRRLIB_BLEND_ALPHA;
} }
/** /**
* Call this function after drawing. * Call this function after drawing.
*/ */
void GRRLIB_Render() { void GRRLIB_Render() {
//GX_Flush();
GX_DrawDone(); GX_DrawDone();
fb ^= 1; // Flip framebuffer fb ^= 1; // Flip framebuffer
@ -1229,8 +1201,9 @@ void GRRLIB_Exit() {
GX_SetScissor( 0, 0, rmode->fbWidth, rmode->efbHeight ); GX_SetScissor( 0, 0, rmode->fbWidth, rmode->efbHeight );
GRRLIB_FillScreen( 0x000000FF ); GRRLIB_FillScreen( 0x000000FF );
GRRLIB_Render(); GRRLIB_Render();
GX_Flush(); GX_DrawDone();
GX_AbortFrame(); GX_AbortFrame();
GX_Flush();
if (xfb[0] != NULL) { if (xfb[0] != NULL) {
free(MEM_K1_TO_K0(xfb[0])); free(MEM_K1_TO_K0(xfb[0]));

View file

@ -25,11 +25,12 @@
*/ */
#define GRRLIB_BLEND_ALPHA 0 /**< Alpha Blending. */ #define GRRLIB_BLEND_ALPHA 0 /**< Alpha Blending. */
#define GRRLIB_BLEND_ADD 1 /**< Additive Blending. */ #define GRRLIB_BLEND_ADD 1 /**< Additive Blending. */
#define GRRLIB_BLEND_SUB 2 /**< Subtractive Blending. */ #define GRRLIB_BLEND_SCREEN 2 /**< Alpha Light Blending */
#define GRRLIB_BLEND_INV 3 /**< Invertive Blending. */ #define GRRLIB_BLEND_MULTI 3 /**< Multiply Blending. */
#define GRRLIB_BLEND_INV 4 /**< Invert Color Blending. */
#define GRRLIB_BLEND_NONE GRRLIB_BLEND_ALPHA #define GRRLIB_BLEND_NONE GRRLIB_BLEND_ALPHA
#define GRRLIB_BLEND_LIGHT GRRLIB_BLEND_ADD #define GRRLIB_BLEND_LIGHT GRRLIB_BLEND_ADD
#define GRRLIB_BLEND_SHADE GRRLIB_BLEND_SUB #define GRRLIB_BLEND_SHADE GRRLIB_BLEND_MULTI
/** /**