(I probably shouldn't be doing this, but I'm that desperate for an answer. You'll understand when you see it.)
Once again, my google skills failed me.
Do you people have any examples of code that does multiple textures on a single polygon in GX hardware for Wii, that you're not using right now?
I'm having some issues with z-fighting on a project I'm working on, and I think that's because it is trying to blend 2 polygons with different textures, when the coordinates of such polygons can't really be guaranteed to be the same in code.
Besides, I really would like to learn how to do multitexturing.
Any help you can give me will be highly appreciated!
Multitexturing in GX for Wii?
-
- Site Admin
- Posts: 1861
- Joined: Tue Aug 09, 2005 3:21 am
- Location: UK
- Contact:
Re: Multitexturing in GX for Wii?
Not sure what you googled for but a brief search turned this up for me.
http://www.chadheim.com/projects/projectfps/
If you feel like digging out the technical bits of that code and creating a multitexturing example it would be much appreciated.
http://www.chadheim.com/projects/projectfps/
If you feel like digging out the technical bits of that code and creating a multitexturing example it would be much appreciated.
Re: Multitexturing in GX for Wii?
@WinterMute: As usual, right on target!
Incidentally, what were your search terms? I have this crazy theory that Google does different searches for different people in different countries; mine are almost always the wrong ones.
----------------------------------------------
As it turned out, it was extremely simple. You just need to:
1) Tell GX you will set 2 or more texcoords to generate ( GX_SetNumTexGens(2); GX_SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY); );
2) Tell GX you will use 2 or more TEV stages ( GX_SetNumTevStages(2); );
3) Tell GX how will pixels from previous stages will blend with the following ones ( GX_SetTevOp(GX_TEVSTAGE1, GX_BLEND); );
4) Specify which stages get which textures ( GX_LoadTexObj(&tex1, GX_TEXMAP0); GX_LoadTexObj(&tex2, GX_TEXMAP1); );
5) Alter your vertex descriptors appropiately ( GX_SetVtxDesc(GX_VA_TEX1, GX_DIRECT); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_TEX_ST, GX_F32, 0); );
6) And, of course, call the appropiate texcoord specification functions twice or more, even if they use the same values ( GX_TexCoord2f32(0.0f,1.0f); GX_TexCoord2f32(0.0f,1.0f); ).
For posterity, I'll post the program that does all of these:
(The code came from this: NeHe lesson 6 modified for GX, THEN for multitexturing.
Incidentally, what were your search terms? I have this crazy theory that Google does different searches for different people in different countries; mine are almost always the wrong ones.
----------------------------------------------
As it turned out, it was extremely simple. You just need to:
1) Tell GX you will set 2 or more texcoords to generate ( GX_SetNumTexGens(2); GX_SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY); );
2) Tell GX you will use 2 or more TEV stages ( GX_SetNumTevStages(2); );
3) Tell GX how will pixels from previous stages will blend with the following ones ( GX_SetTevOp(GX_TEVSTAGE1, GX_BLEND); );
4) Specify which stages get which textures ( GX_LoadTexObj(&tex1, GX_TEXMAP0); GX_LoadTexObj(&tex2, GX_TEXMAP1); );
5) Alter your vertex descriptors appropiately ( GX_SetVtxDesc(GX_VA_TEX1, GX_DIRECT); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_TEX_ST, GX_F32, 0); );
6) And, of course, call the appropiate texcoord specification functions twice or more, even if they use the same values ( GX_TexCoord2f32(0.0f,1.0f); GX_TexCoord2f32(0.0f,1.0f); ).
For posterity, I'll post the program that does all of these:
(The code came from this: NeHe lesson 6 modified for GX, THEN for multitexturing.
Code: Select all
/*---------------------------------------------------------------------------------
multitexture
modification to nehe lesson 6 port to GX, showing multiple textures per polygon
original port: shagkur
modifications: Izhido
---------------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <gccore.h>
#include <wiiuse/wpad.h>
// The two textures to use in this lesson
#include "crate_tpl.h"
#include "crate.h"
#include "NeHe_tpl.h"
#include "NeHe.h"
#define DEFAULT_FIFO_SIZE (256*1024)
static GXRModeObj *rmode = NULL;
static void *frameBuffer[2] = { NULL, NULL};
int main(int argc,char **argv)
{
f32 yscale;
u32 xfbHeight;
u32 fb = 0;
f32 rquad = 0.0f;
u32 first_frame = 1;
GXTexObj textureNeHe;
GXTexObj texturecrate;
Mtx view; // view and perspective matrices
Mtx model, modelview;
Mtx44 perspective;
void *gpfifo = NULL;
GXColor background = {0, 0, 0, 0xff};
guVector cam = {0.0F, 0.0F, 0.0F},
up = {0.0F, 1.0F, 0.0F},
look = {0.0F, 0.0F, -1.0F};
TPLFile neheTPL;
TPLFile crateTPL;
VIDEO_Init();
WPAD_Init();
rmode = VIDEO_GetPreferredMode(NULL);
// allocate the fifo buffer
gpfifo = memalign(32,DEFAULT_FIFO_SIZE);
memset(gpfifo,0,DEFAULT_FIFO_SIZE);
// allocate 2 framebuffers for double buffering
frameBuffer[0] = SYS_AllocateFramebuffer(rmode);
frameBuffer[1] = SYS_AllocateFramebuffer(rmode);
// configure video
VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(frameBuffer[fb]);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
fb ^= 1;
// init the flipper
GX_Init(gpfifo,DEFAULT_FIFO_SIZE);
// clears the bg to color and clears the z buffer
GX_SetCopyClear(background, 0x00ffffff);
// other gx setup
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);
// setup the vertex attribute table
// describes the data
// args: vat location 0-7, type of data, data format, size, scale
// so for ex. in the first call we are sending position data with
// 3 values X,Y,Z of size F32. scale sets the number of fractional
// bits for non float data.
// An additional descriptor is added for a second texture.
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX1, GX_DIRECT); // <-- Texcoords for the second TEV
// Though not really relevant, the items here were rearranged
// so they match the previous lines
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGB8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_TEX_ST, GX_F32, 0);
// set number of rasterized color channels
GX_SetNumChans(1);
//set number of texture coordinates to generate (two, for multitexture)
GX_SetNumTexGens(2);
// setup texture coordinate generation
// args: texcoord slot 0-7, matrix type, source to generate texture coordinates from, matrix to use
// The setup gets duplicated for both textures
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY);
GX_InvVtxCache();
GX_InvalidateTexAll();
// Opening both textures from header files
TPL_OpenTPLFromMemory(&crateTPL, (void *)crate_tpl,crate_tpl_size);
TPL_GetTexture(&crateTPL,crate,&texturecrate);
TPL_OpenTPLFromMemory(&neheTPL, (void *)NeHe_tpl,NeHe_tpl_size);
TPL_GetTexture(&neheTPL,nehe,&textureNeHe);
// setup our camera at the origin
// looking down the -z axis with y up
guLookAt(view, &cam, &up, &look);
// setup our projection matrix
// this creates a perspective matrix with a view angle of 90,
// and aspect ratio based on the display resolution
f32 w = rmode->viWidth;
f32 h = rmode->viHeight;
guPerspective(perspective, 45, (f32)w/h, 0.1F, 300.0F);
GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE);
guVector cubeAxis = {1,1,1};
while(1) {
WPAD_ScanPads();
if ( WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);
// Sets the number of TEV stages, so as to indicate we're using 2 textures.
// These lines do not really belong in here, since they can be called
// outside this loop; this was made to be consistent with the original ported example:
GX_SetNumTevStages(2);
// The first texture is used as the base for the cube; that is,
// the cube is intended to be a "crate":
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE); // <-- Overwrite anything existing at that location
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
// The second texture is blended with the first, giving it the impression
// of being a "sticker" plastered over the crate:
GX_SetTevOp(GX_TEVSTAGE1, GX_BLEND); // <-- Blend with previous texture
GX_SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0);
guMtxIdentity(model);
guMtxRotAxisDeg(model, &cubeAxis, rquad);
guMtxTransApply(model, model, 1.5f,0.0f,-7.0f);
guMtxConcat(view,model,modelview);
// load the modelview matrix into matrix memory
GX_LoadPosMtxImm(modelview, GX_PNMTX0);
GX_LoadTexObj(&texturecrate, GX_TEXMAP0);
GX_LoadTexObj(&textureNeHe, GX_TEXMAP1);
GX_Begin(GX_QUADS, GX_VTXFMT0, 24); // Draw a Cube
GX_Position3f32(-1.0f, 1.0f, -1.0f); // Top Left of the quad (top)
GX_Color3f32(0.0f,1.0f,0.0f); // Set The Color To Green
GX_TexCoord2f32(0.0f,0.0f);
GX_TexCoord2f32(0.0f,0.0f);
GX_Position3f32(-1.0f, 1.0f, 1.0f); // Top Right of the quad (top)
GX_Color3f32(0.0f,1.0f,0.0f); // Set The Color To Green
GX_TexCoord2f32(1.0f,0.0f);
GX_TexCoord2f32(1.0f,0.0f);
GX_Position3f32(-1.0f, -1.0f, 1.0f); // Bottom Right of the quad (top)
GX_Color3f32(0.0f,1.0f,0.0f); // Set The Color To Green
GX_TexCoord2f32(1.0f,1.0f);
GX_TexCoord2f32(1.0f,1.0f);
GX_Position3f32(- 1.0f, -1.0f, -1.0f); // Bottom Left of the quad (top)
GX_Color3f32(0.0f,1.0f,0.0f); // Set The Color To Green
GX_TexCoord2f32(0.0f,1.0f);
GX_TexCoord2f32(0.0f,1.0f);
GX_Position3f32( 1.0f,1.0f, -1.0f); // Top Left of the quad (bottom)
GX_Color3f32(1.0f,0.5f,0.0f); // Set The Color To Orange
GX_TexCoord2f32(0.0f,0.0f);
GX_TexCoord2f32(0.0f,0.0f);
GX_Position3f32(1.0f,-1.0f, -1.0f); // Top Right of the quad (bottom)
GX_Color3f32(1.0f,0.5f,0.0f); // Set The Color To Orange
GX_TexCoord2f32(1.0f,0.0f);
GX_TexCoord2f32(1.0f,0.0f);
GX_Position3f32(1.0f,-1.0f,1.0f); // Bottom Right of the quad (bottom)
GX_Color3f32(1.0f,0.5f,0.0f); // Set The Color To Orange
GX_TexCoord2f32(1.0f,1.0f);
GX_TexCoord2f32(1.0f,1.0f);
GX_Position3f32( 1.0f,1.0f,1.0f); // Bottom Left of the quad (bottom)
GX_Color3f32(1.0f,0.5f,0.0f); // Set The Color To Orange
GX_TexCoord2f32(0.0f,1.0f);
GX_TexCoord2f32(0.0f,1.0f);
GX_Position3f32( -1.0f, -1.0f, 1.0f); // Top Right Of The Quad (Front)
GX_Color3f32(1.0f,0.0f,0.0f); // Set The Color To Red
GX_TexCoord2f32(0.0f,0.0f);
GX_TexCoord2f32(0.0f,0.0f);
GX_Position3f32(1.0f, -1.0f, 1.0f); // Top Left Of The Quad (Front)
GX_Color3f32(1.0f,0.0f,0.0f); // Set The Color To Red
GX_TexCoord2f32(1.0f,0.0f);
GX_TexCoord2f32(1.0f,0.0f);
GX_Position3f32(1.0f,-1.0f, -1.0f); // Bottom Left Of The Quad (Front)
GX_Color3f32(1.0f,0.0f,0.0f); // Set The Color To Red
GX_TexCoord2f32(1.0f,1.0f);
GX_TexCoord2f32(1.0f,1.0f);
GX_Position3f32( -1.0f,-1.0f, -1.0f); // Bottom Right Of The Quad (Front)
GX_Color3f32(1.0f,0.0f,0.0f); // Set The Color To Red
GX_TexCoord2f32(0.0f,1.0f);
GX_TexCoord2f32(0.0f,1.0f);
GX_Position3f32( -1.0f,1.0f,1.0f); // Bottom Left Of The Quad (Back)
GX_Color3f32(1.0f,1.0f,0.0f); // Set The Color To Yellow
GX_TexCoord2f32(0.0f,0.0f);
GX_TexCoord2f32(0.0f,0.0f);
GX_Position3f32(-1.0f,1.0f,-1.0f); // Bottom Right Of The Quad (Back)
GX_Color3f32(1.0f,1.0f,0.0f); // Set The Color To Yellow
GX_TexCoord2f32(1.0f,0.0f);
GX_TexCoord2f32(1.0f,0.0f);
GX_Position3f32(1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Back)
GX_Color3f32(1.0f,1.0f,0.0f); // Set The Color To Yellow
GX_TexCoord2f32(1.0f,1.0f);
GX_TexCoord2f32(1.0f,1.0f);
GX_Position3f32( 1.0f, 1.0f,1.0f); // Top Left Of The Quad (Back)
GX_Color3f32(1.0f,1.0f,0.0f); // Set The Color To Yellow
GX_TexCoord2f32(0.0f,1.0f);
GX_TexCoord2f32(0.0f,1.0f);
GX_Position3f32(1.0f, -1.0f, -1.0f); // Top Right Of The Quad (Left)
GX_Color3f32(0.0f,0.0f,1.0f); // Set The Color To Blue
GX_TexCoord2f32(0.0f,0.0f);
GX_TexCoord2f32(0.0f,0.0f);
GX_Position3f32(1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
GX_Color3f32(0.0f,0.0f,1.0f); // Set The Color To Blue
GX_TexCoord2f32(1.0f,0.0f);
GX_TexCoord2f32(1.0f,0.0f);
GX_Position3f32(-1.0f,1.0f,-1.0f); // Bottom Left Of The Quad (Left)
GX_Color3f32(0.0f,0.0f,1.0f); // Set The Color To Blue
GX_TexCoord2f32(1.0f,1.0f);
GX_TexCoord2f32(1.0f,1.0f);
GX_Position3f32(-1.0f,-1.0f, -1.0f); // Bottom Right Of The Quad (Left)
GX_Color3f32(0.0f,0.0f,1.0f); // Set The Color To Blue
GX_TexCoord2f32(0.0f,1.0f);
GX_TexCoord2f32(0.0f,1.0f);
GX_Position3f32( 1.0f, -1.0f,1.0f); // Top Right Of The Quad (Right)
GX_Color3f32(1.0f,0.0f,1.0f); // Set The Color To Violet
GX_TexCoord2f32(0.0f,0.0f);
GX_TexCoord2f32(0.0f,0.0f);
GX_Position3f32( -1.0f, -1.0f, 1.0f); // Top Left Of The Quad (Right)
GX_Color3f32(1.0f,0.0f,1.0f); // Set The Color To Violet
GX_TexCoord2f32(1.0f,0.0f);
GX_TexCoord2f32(1.0f,0.0f);
GX_Position3f32( -1.0f,1.0f, 1.0f); // Bottom Left Of The Quad (Right)
GX_Color3f32(1.0f,0.0f,1.0f); // Set The Color To Violet
GX_TexCoord2f32(1.0f,1.0f);
GX_TexCoord2f32(1.0f,1.0f);
GX_Position3f32( 1.0f,1.0f,1.0f); // Bottom Right Of The Quad (Right)
GX_Color3f32(1.0f,0.0f,1.0f); // Set The Color To Violet
GX_TexCoord2f32(0.0f,1.0f);
GX_TexCoord2f32(0.0f,1.0f);
GX_End(); // Done Drawing The Quad
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
GX_CopyDisp(frameBuffer[fb],GX_TRUE);
GX_DrawDone();
VIDEO_SetNextFramebuffer(frameBuffer[fb]);
if(first_frame) {
first_frame = 0;
VIDEO_SetBlack(FALSE);
}
VIDEO_Flush();
VIDEO_WaitVSync();
fb ^= 1;
rquad -= 0.15f; // Decrease The Rotation Variable For The Quad ( NEW )
}
}
Who is online
Users browsing this forum: Google [Bot] and 1 guest