Billboards - alpha testing failing on just *some* textures

Post Reply
MontyOnTheRun
Posts: 2
Joined: Tue Dec 12, 2023 8:27 pm

Billboards - alpha testing failing on just *some* textures

Post by MontyOnTheRun » Tue Dec 12, 2023 8:55 pm

Hello all.
Thank you for the space and for the hard work!

I've been trying to port my game engine to the Gamecube and Wii, but somehow I can't seem to render my billboards without the texture border.
What's odd is that, for bitmapped fonts and some other 2D elements, it renders fine!

Image

If I try to load some texture at the same time I was loading the fonts, it will work fine. If I use the same code at some other time, it will render the borders (It should be noted that I'm loading my textures from my own binary blob instead of using TPLs).

My code is also heavily based on neheGX.

My initialization:

Code: Select all

VIDEO_Init();
    
#ifdef GX
    PAD_Init();
#endif

#ifdef WII
    WPAD_Init();
#endif

    rmode = VIDEO_GetPreferredMode(NULL);

    gpfifo = memalign(32,DEFAULT_FIFO_SIZE);
    memset(gpfifo,0,DEFAULT_FIFO_SIZE);

    frameBuffer[0] = SYS_AllocateFramebuffer(rmode);
    frameBuffer[1] = SYS_AllocateFramebuffer(rmode);

    VIDEO_Configure(rmode);
    VIDEO_SetNextFramebuffer(frameBuffer[fb]);
    VIDEO_Flush();
    VIDEO_WaitVSync();
    if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();

    fb ^= 1;

    GX_Init(gpfifo,DEFAULT_FIFO_SIZE);

    GX_SetCopyClear(background, 0x00ffffff);

    GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1);
    yscale = GX_GetYScaleFactor(rmode->efbHeight,rmode->xfbHeight);
    xfbHeight = GX_SetDispCopyYScale(yscale);
    GX_SetScissor(0,0,rmode->fbWidth,rmode->efbHeight);
    GX_SetDispCopySrc(0,0,rmode->fbWidth,rmode->efbHeight);
    GX_SetDispCopyDst(rmode->fbWidth,xfbHeight);
    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));

    if (rmode->aa) {
        GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR);
    } else {
        GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
    }

    GX_SetCullMode(GX_CULL_NONE);
    GX_CopyDisp(frameBuffer[fb],GX_TRUE);
    GX_SetDispCopyGamma(GX_GM_1_0);

    GX_ClearVtxDesc();
    GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
    GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
    GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);

    GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
    GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
    GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGB8, 0);

    GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);

    GX_SetTevOp(GX_TEVSTAGE0,GX_MODULATE);
    GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);

    GX_SetNumTexGens(1);
    GX_SetNumChans(1);
    GX_InvVtxCache();
    GX_InvalidateTexAll();

    GX_SetAlphaUpdate(GX_TRUE);
    GX_SetAlphaCompare(GX_GREATER,0,GX_AOP_AND,GX_ALWAYS,0);

    memset(&whiteTextureData[0], 0xFF, 32 * 32 * 4);

    GX_InitTexObj(&whiteTextureObj, &whiteTextureData[0], 32, 32, GX_TF_RGBA8, GX_REPEAT, GX_REPEAT, GX_FALSE);
    
(yes, I'm using a white texture for plotting solid shapes. I'm not entirely sure how this could be better performed)

Of course, at some point the perspective is also set, but given how the billboard renders corectly (if we ignore the border, which is RGBA #00000000, BTW), I don't see this as an issue.

How am I loading my textures? Besides all the memory allocation (properly aligned) and stuff, once I have my raw RGBA bitmap loaded (and taking into consideration the texture block arrangement), I issue:

Code: Select all

    
    DCFlushRange(bitmap->data, bitmap->width * bitmap->height * 4);
    GX_InitTexObj(bitmap->nativeBuffer, bitmap->data, bitmap->width, bitmap->height, GX_TF_RGBA8, GX_REPEAT, GX_REPEAT, GX_FALSE);
And finally, the binding:

Code: Select all

GX_LoadTexObj(bitmap->nativeBuffer, GX_TEXMAP0);
The polygon drawing code is very straightforward:

Code: Select all

    GX_Begin(GX_QUADS, GX_VTXFMT0, 4);	

    GX_Position3f32(vx1, vy1, vz1);
    GX_Color3f32(1,1,1);
    GX_TexCoord2f32(u1, v1);

    GX_Position3f32( vx2, vy2, vz2);
    GX_Color3f32(1,1,1);
    GX_TexCoord2f32(u2, v2);

    GX_Position3f32(vx4, vy4, vz4);
    GX_Color3f32(1,1,1);
    GX_TexCoord2f32(u4, v4);

    GX_Position3f32( vx3, vy3, vz3);
    GX_Color3f32(1,1,1);
    GX_TexCoord2f32(u3, v3);

    GX_End();
This code is a port from an OpenGL version (written for the N64's LibDragon and NDS's devkit GL wrapper, but also supporting PPC Macs and newer stuff), from what was originally a software rendering engine (thank you guys for allowing me to support the GBA on that!)

I'm on my wit's end. I hope you guys could help me figuring out what I'm missing, please?

MontyOnTheRun
Posts: 2
Joined: Tue Dec 12, 2023 8:27 pm

Re: Billboards - alpha testing failing on just *some* textures

Post by MontyOnTheRun » Sun Dec 17, 2023 1:09 am

Fixed!

Image

Turns out I needed to issue GX_SetZCompLoc(GX_FALSE);
Heck, the docs even mention my case as an example!

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest