void draw_pointer( f32 x, f32 y, f32 ang, u8 r, u8 g, u8 b ) { Mtx m,mv; guMtxRotAxisDeg( m, &rotax, ang ); guMtxTransApply( m, m, x, y, 0 ); guMtxConcat( GXmodelView2D, m, mv ); GX_LoadPosMtxImm( mv, GX_PNMTX0 ); GX_Begin( GX_TRIANGLES, GX_VTXFMT0, 3 ); GX_Position3f32( 0.0f, 0.0f, 19.0f ); GX_Color4u8( r, g, b, 0xa0 ); GX_Position3f32( 32.0f, 16.0f, 19.0f ); GX_Color4u8( r, g, b, 0xa0 ); GX_Position3f32( 16.0f, 32.0f, 19.0f ); GX_Color4u8( r, g, b, 0xa0 ); GX_End(); GX_Begin( GX_LINESTRIP, GX_VTXFMT0, 4 ); GX_Position3f32( 0.0f, 0.0f, 19.0f ); GX_Color4u8( 0, 0, 0, 0xff ); GX_Position3f32( 32.0f, 16.0f, 19.0f ); GX_Color4u8( 0, 0, 0, 0xff ); GX_Position3f32( 16.0f, 32.0f, 19.0f ); GX_Color4u8( 0, 0, 0, 0xff ); GX_Position3f32( 0.0f, 0.0f, 19.0f ); GX_Color4u8( 0, 0, 0, 0xff ); GX_End(); GX_LoadPosMtxImm (GXmodelView2D, GX_PNMTX0); }
/**************************************************************************** * Menu_DrawImg * * Draws the specified image on screen using GX ***************************************************************************/ void Menu_DrawImg(f32 xpos, f32 ypos, u16 width, u16 height, u8 data[], f32 degrees, f32 scaleX, f32 scaleY, u8 alpha) { if(data == NULL) return; GXTexObj texObj; GX_InitTexObj(&texObj, data, width, height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_LoadTexObj(&texObj, GX_TEXMAP0); GX_InvalidateTexAll(); GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE); GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT); Mtx m,m1,m2, mv; width >>= 1; height >>= 1; guMtxIdentity (m1); guMtxScaleApply(m1,m1,scaleX,scaleY,1.0); guVector axis = (guVector) {0 , 0, 1 }; guMtxRotAxisDeg (m2, &axis, degrees); guMtxConcat(m2,m1,m); guMtxTransApply(m,m, xpos+width,ypos+height,0); guMtxConcat (GXmodelView2D, m, mv); GX_LoadPosMtxImm (mv, GX_PNMTX0); GX_Begin(GX_QUADS, GX_VTXFMT0,4); GX_Position3f32(-width, -height, 0); GX_Color4u8(0xFF,0xFF,0xFF,alpha); GX_TexCoord2f32(0, 0); GX_Position3f32(width, -height, 0); GX_Color4u8(0xFF,0xFF,0xFF,alpha); GX_TexCoord2f32(1, 0); GX_Position3f32(width, height, 0); GX_Color4u8(0xFF,0xFF,0xFF,alpha); GX_TexCoord2f32(1, 1); GX_Position3f32(-width, height, 0); GX_Color4u8(0xFF,0xFF,0xFF,alpha); GX_TexCoord2f32(0, 1); GX_End(); GX_LoadPosMtxImm (GXmodelView2D, GX_PNMTX0); GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR); GX_SetVtxDesc (GX_VA_TEX0, GX_NONE); }
void DrawScene(Mtx view) { Mtx model,modelview; // Various matrices guVector axis; // Axis to rotate on // BUG: Light ignores underlying polygon colors. SetLight(view); // Setup the light for (yloop = 1; yloop < 6; yloop++) { // Loop through the y plane for (xloop = 0; xloop < yloop; xloop++) { // Loop through the x plane // Position the cubes on the screen guMtxIdentity(model); axis.x = 1.0f; axis.y = 0; axis.z = 0; guMtxRotAxisDeg(model,&axis,(45.0f-(2.0f*(float)yloop)+xrot)); // Tilt the cubes up and down axis.x = 0; axis.y = 1.0f; guMtxRotAxisDeg(model,&axis,(45.0f+yrot)); // Spin cubes left and right guMtxTransApply(model,model,(1.4f+((float)xloop*2.8f)-((float)yloop*1.4f)),(((6.0f-(float)yloop)*2.2f)-7.0f),-20.0f); guMtxConcat(model,view,modelview); GX_LoadPosMtxImm(modelview, GX_PNMTX0); GX_CallDispList(boxList[yloop-1],boxSize[yloop-1]); // Draw the box } } }
// rulez nyan scene int main(int argc, char **argv) { bool nyaning = true; // self explain nyan(); MP3Player_PlayBuffer(nyannyannyan_mp3, nyannyannyan_mp3_size, NULL); VIDEO_SetBlack(FALSE); while(nyaning) { u64 cticks = ticks_to_millisecs(gettime()); // Loop the sound if ended if(!MP3Player_IsPlaying()) MP3Player_PlayBuffer(nyannyannyan_mp3, nyannyannyan_mp3_size, NULL); //Check wiimote input WPAD_ScanPads(); u32 pressed = WPAD_ButtonsDown(0); if (pressed & WPAD_BUTTON_HOME) nyaning = false; // blackscreen until 3,8s like the youtube video (not extreme precison ;)) if(cticks < startTime+3900) continue; // bkg frame counter (tick each 100ms) if(cticks > bkgTimeCounter+100) { bkgTimeCounter = cticks; currentBkgStep = (currentBkgStep+1) % BKG_STEP; } // nyan frame counter (tick each 60ms) if(cticks > nyanTimeCounter+60) { nyanTimeCounter = cticks; currentNyanStep = (currentNyanStep+1) % NYAN_STEP; } // Set the 2d matrix guMtxIdentity(GXmodelView2D); GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0); // nyan f32 move = delta % BKG_SIZE; f32 x = -move; while(x < rmode->fbWidth) { drawBkgSprite(x, currentBkgStep); x += BKG_SIZE; } // nyan nyan drawNyan(-5, 240 - ((NYAN_HEIGHT*8)/2), currentNyanStep); // Copy & switch fb GX_DrawDone(); GX_CopyDisp(xfb[wichFb], GX_TRUE); VIDEO_SetNextFramebuffer(xfb[wichFb]); VIDEO_Flush(); VIDEO_WaitVSync(); wichFb ^= 1; delta += 8; } return 0; }
void draw_sun( f32 x, f32 y, f32 r, f32 ang, u8 *col ) { int i; Mtx m, mv; circle( x, y, r, col, 1, 100, 0.0f ); guMtxIdentity( m ); guMtxRotAxisRad( m, &rotax, ang ); guMtxTransApply( m, m, x, y, 0 ); guMtxConcat( GXmodelView2D, m, mv ); GX_LoadPosMtxImm( mv, GX_PNMTX0 ); GX_Begin( GX_QUADS, GX_VTXFMT0, NUMRAYS*4 ); for( i=0; i<NUMRAYS; i++ ) { GX_Position3f32( sunrays[i*4 ].x , sunrays[i*4 ].y , 0.0f ); GX_Color4u8( col[0], col[1], col[2], 0xff ); GX_Position3f32( sunrays[i*4+1].x , sunrays[i*4+1].y , 0.0f ); GX_Color4u8( col[0], col[1], col[2], 0xff ); GX_Position3f32( sunrays[i*4+2].x*0.9f, sunrays[i*4+2].y*0.9f, 0.0f ); GX_Color4u8( col[0], col[1], col[2], 0xff ); GX_Position3f32( sunrays[i*4+3].x*0.9f, sunrays[i*4+3].y*0.9f, 0.0f ); GX_Color4u8( col[0], col[1], col[2], 0xff ); } GX_End(); for( i=0; i<NUMRAYS; i++ ) { GX_Begin( GX_LINESTRIP, GX_VTXFMT0, 4 ); GX_Position3f32( sunrays[i*4+3].x, sunrays[i*4+3].y, 0.0f ); GX_Color4u8( 0, 0, 0, 0xff ); GX_Position3f32( sunrays[i*4 ].x, sunrays[i*4 ].y, 0.0f ); GX_Color4u8( 0, 0, 0, 0xff ); GX_Position3f32( sunrays[i*4+1].x, sunrays[i*4+1].y, 0.0f ); GX_Color4u8( 0, 0, 0, 0xff ); GX_Position3f32( sunrays[i*4+2].x, sunrays[i*4+2].y, 0.0f ); GX_Color4u8( 0, 0, 0, 0xff ); GX_End(); } GX_LoadPosMtxImm (GXmodelView2D, GX_PNMTX0); GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR); GX_SetVtxDesc (GX_VA_TEX0, GX_NONE); }
void Util3D::Trans(f32 xpos, f32 ypos) { Mtx Matrix, Final; guMtxIdentity(Matrix); guMtxTrans(Matrix,xpos, ypos, 0 ); // Position guMtxConcat(Singleton<WiiManager>::GetInstanceByRef().GetCamera()->GetcameraMatrix(),Matrix,Final); GX_LoadPosMtxImm (Final, GX_PNMTX0); }
void Util3D::TransScale(f32 xpos, f32 ypos, f32 zpos , f32 scale) { Mtx FinalMatrix,TransMatrix; guMtxScale(TransMatrix,scale,scale,scale); guMtxTransApply(TransMatrix,TransMatrix,xpos, ypos, zpos ); // Position guMtxConcat(Singleton<WiiManager>::GetInstanceByRef().GetCamera()->GetcameraMatrix(),TransMatrix,FinalMatrix); GX_LoadPosMtxImm (FinalMatrix, GX_PNMTX0); }
void Util3D::TransRot(f32 xpos, f32 ypos, f32 rad) { Mtx FinalMatrix,TransMatrix; MatrixRotateZ(TransMatrix,rad); //guMtxRotRad(TransMatrix,'Z',rad); // Rotage guMtxTransApply(TransMatrix,TransMatrix,xpos, ypos, 0.0f ); // Position guMtxConcat(Singleton<WiiManager>::GetInstanceByRef().GetCamera()->GetcameraMatrix(),TransMatrix,FinalMatrix); GX_LoadPosMtxImm (FinalMatrix, GX_PNMTX0); }
void prepairForSeriousDrawing(){ // do this before drawing GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1); guMtxIdentity(model); guMtxTransApply(model, model, -1.5f,0.0f,-6.0f); guMtxConcat(view,model,modelview); // load the modelview matrix into matrix memory GX_LoadPosMtxImm(modelview, GX_PNMTX0); }
/**************************************************************************** * Menu_DrawImg * * Draws the specified image on screen using GX ***************************************************************************/ void Menu_DrawImg(f32 xpos, f32 ypos, f32 zpos, f32 width, f32 height, u8 data[], f32 degrees, f32 scaleX, f32 scaleY, u8 alpha, int XX1, int YY1, int XX2, int YY2, int XX3, int YY3, int XX4, int YY4) { if (data == NULL) return; GX_LoadProjectionMtx(FSProjection2D, GX_ORTHOGRAPHIC); GXTexObj texObj; GX_InitTexObj(&texObj, data, width, height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_LoadTexObj(&texObj, GX_TEXMAP0); GX_ClearVtxDesc(); GX_InvVtxCache(); GX_InvalidateTexAll(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); Mtx m, m1, m2, mv; width *= 0.5f; height *= 0.5f; guMtxIdentity(m1); guMtxScaleApply(m1, m1, scaleX, scaleY, 1.0f); guVector axis = (guVector) {0 , 0, 1}; guMtxRotAxisDeg (m2, &axis, degrees); guMtxConcat(m1, m2, m); guMtxTransApply(m, m, xpos + width + 0.5f, ypos + height + 0.5f, zpos); guMtxConcat(FSModelView2D, m, mv); GX_LoadPosMtxImm(mv, GX_PNMTX0); GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position3f32(-width + XX1, -height + YY1, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, alpha); GX_TexCoord2f32(0, 0); GX_Position3f32(width + XX2, -height + YY2, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, alpha); GX_TexCoord2f32(1, 0); GX_Position3f32(width + XX3, height + YY3, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, alpha); GX_TexCoord2f32(1, 1); GX_Position3f32(-width + XX4, height + YY4, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, alpha); GX_TexCoord2f32(0, 1); GX_End(); }
void draw_star( f32 scale, f32 angle, f32 x, f32 y, u8 *col, u8 alpha ) { int i, j; Mtx m,m1,m2,mv; guMtxIdentity(m1); guMtxScaleApply( m1, m1, scale, scale, 1.0f ); guMtxRotAxisRad( m2, &rotax, angle ); guMtxConcat( m2, m1, m); guMtxTransApply( m, m, x, y, 0 ); guMtxConcat( GXmodelView2D, m, mv ); GX_LoadPosMtxImm( mv, GX_PNMTX0 ); GX_Begin( GX_TRIANGLES, GX_VTXFMT0, 3*NUM_STAR_POLYS ); for( i=0; i<NUM_STAR_POLYS*3; i++ ) { j = star_polys[i]*2; GX_Position3f32( star_pts[j], star_pts[j+1], 0.0f ); GX_Color4u8( col[0], col[1], col[2], alpha ); } GX_End(); GX_Begin( GX_LINESTRIP, GX_VTXFMT0, NUM_STAR_EDGES ); for( i=0; i<NUM_STAR_EDGES; i++ ) { j = star_edges[i]*2; GX_Position3f32( star_pts[j], star_pts[j+1], 0.0f ); GX_Color4u8( 0, 0, 0, alpha ); } GX_End(); GX_LoadPosMtxImm (GXmodelView2D, GX_PNMTX0); GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR); GX_SetVtxDesc (GX_VA_TEX0, GX_NONE); }
void drawInit() { Mtx44 GXprojection2D; Mtx GXmodelView2D; // Reset various parameters from gfx plugin GX_SetCoPlanar(GX_DISABLE); GX_SetClipMode(GX_CLIP_ENABLE); // GX_SetScissor(0,0,vmode->fbWidth,vmode->efbHeight); GX_SetAlphaCompare(GX_ALWAYS,0,GX_AOP_AND,GX_ALWAYS,0); guMtxIdentity(GXmodelView2D); GX_LoadTexMtxImm(GXmodelView2D,GX_TEXMTX0,GX_MTX2x4); GX_LoadPosMtxImm(GXmodelView2D,GX_PNMTX0); guOrtho(GXprojection2D, 0, 479, 0, 639, 0, 700); GX_LoadProjectionMtx(GXprojection2D, GX_ORTHOGRAPHIC); // GX_SetViewport (0, 0, vmode->fbWidth, vmode->efbHeight, 0, 1); GX_SetZMode(GX_DISABLE,GX_ALWAYS,GX_TRUE); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_PTNMTXIDX, GX_PNMTX0); GX_SetVtxDesc(GX_VA_TEX0MTXIDX, GX_TEXMTX0); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); //set vertex attribute formats here GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 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); //enable textures GX_SetNumChans (1); GX_SetNumTexGens (1); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GX_SetNumTevStages (1); GX_SetTevOrder (GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR); //set blend mode GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); //Fix src alpha GX_SetColorUpdate(GX_ENABLE); // GX_SetAlphaUpdate(GX_ENABLE); // GX_SetDstAlpha(GX_DISABLE, 0xFF); //set cull mode GX_SetCullMode (GX_CULL_NONE); }
void QuadPane::Draw(const BannerResources& resources, u8 render_alpha, const float ws_scale, Mtx &modelview, u16 material_index, u8 texture_flip) const { if(!header) return; if (material_index < resources.materials.size()) { bool modulate_color = IsModulateColor(header->vertex_colors, render_alpha); resources.materials[material_index]->Apply(resources, render_alpha, modulate_color); } Mtx m, mv; guMtxIdentity (m); guMtxTransApply(m,m, -0.5f * GetOriginX(), -0.5f * GetOriginY(), 0.f); guMtxScaleApply(m,m, GetWidth(), GetHeight(), 1.f); guMtxConcat (modelview, m, mv); GX_LoadPosMtxImm (mv, GX_PNMTX0); GX_ClearVtxDesc(); GX_InvVtxCache(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); for(u32 i = 0; i < header->tex_coord_count; i++) GX_SetVtxDesc(GX_VA_TEX0+i, GX_DIRECT); GX_Begin(GX_QUADS, GX_VTXFMT0, 4); if(texture_flip) { SetVertex(0, 0.f, 0.f, render_alpha); SetVertex(1, 1.f, 0.f, render_alpha); SetVertex(3, 1.f, 1.f, render_alpha); SetVertex(2, 0.f, 1.f, render_alpha); } else { SetVertex(2, 0.f, 0.f, render_alpha); SetVertex(3, 1.f, 0.f, render_alpha); SetVertex(1, 1.f, 1.f, render_alpha); SetVertex(0, 0.f, 1.f, render_alpha); } GX_End(); }
void render(NODE * node, Vector camPos) { Mtx tmp; if(!node->isRenderable()) return;//Skip non-renderable nodes such as empty nodes, regions or lights if(node->flags & F_Visible)//Is it visible? { //Set matrices Mtx aux, inv; GX_ClearVtxDesc(); node->absMtx(modelM); char msg[64]; guMtxConcat(view, modelM, modelview); GX_LoadPosMtxImm(modelview, GX_PNMTX0);//Load model view matrix guMtxInverse(modelview, tmp); guMtxTranspose(tmp,inv); GX_LoadNrmMtxImm(inv, GX_PNMTX0);//Load normal matrix //TODO: Better lighting (multiple lights) std::vector<LIGHT*>::iterator light = mainRoot->getLights().begin(); //if(light == mainRoot->getLights().end()) // REVConsole->write("LIGHT"); GXLightObj lObj[8]; u8 lightMask = 0, tmpLight = GX_LIGHT0; for(u8 i = 0;light != mainRoot->getLights().end(); ++light, ++i) { Vector lpos = (*light)->getPos(); guVecMultiply(view, &lpos, &lpos); GX_InitLightPos(&lObj[i],lpos.x,lpos.y,lpos.z); GX_InitLightAttn(&lObj[i], 1.0f,0.0f,0.0f,1.0f,0.0f,0.0f); GX_InitLightSpot(&lObj[i],0.0f,GX_SP_OFF); GX_InitLightColor(&lObj[i],(*light)->clr); GX_LoadLightObj(&lObj[i],tmpLight); lightMask |= tmpLight; tmpLight *= 2; } //Render the node node->render(lightMask); } }
/**************************************************************************** * Menu_DrawRectangle * * Draws a rectangle at the specified coordinates using GX ***************************************************************************/ void Menu_DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color, u8 filled) { GX_LoadProjectionMtx(FSProjection2D, GX_ORTHOGRAPHIC); GX_LoadPosMtxImm(FSModelView2D, GX_PNMTX0); GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); GX_ClearVtxDesc(); GX_InvVtxCache(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_NONE); u8 fmt; long n; int i; f32 x2 = x + width; f32 y2 = y + height; guVector v[] = { { x, y, 0.0f }, { x2, y, 0.0f }, { x2, y2, 0.0f }, { x, y2, 0.0f }, { x, y, 0.0f } }; if (!filled) { fmt = GX_LINESTRIP; n = 5; } else { fmt = GX_TRIANGLEFAN; n = 4; } GX_Begin(fmt, GX_VTXFMT0, n); for (i = 0; i < n; i++) { GX_Position3f32(v[i].x, v[i].y, v[i].z); GX_Color4u8(color.r, color.g, color.b, color.a); } GX_End(); GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); }
void Enemy::Draw(Mtx44 view) { Mtx44 model, modelview; guMtxIdentity(model); guMtxIdentity(modelview); guMtxTransApply(model, model, this->x, this->y, this->z); guMtxConcat(view, model, modelview); GX_LoadPosMtxImm(modelview, GX_PNMTX0); GX_LoadTexObj(this->tex, GX_TEXMAP0); f32 width, height; width = this->w / 2.0f; height = this->h / 2.0f; GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position3f32(-width, height, 0); GX_Color4u8(255, 255, 255, 255); if( this->velx > 0 ) GX_TexCoord2f32(1, 0); else GX_TexCoord2f32(0, 0); GX_Position3f32(width, height, 0); GX_Color4u8(255, 255, 255, 255); if( this->velx > 0 ) GX_TexCoord2f32(0, 0); else GX_TexCoord2f32(1, 0); GX_Position3f32(width, -height, 0); GX_Color4u8(255, 255, 255, 255); if( this->velx > 0 ) GX_TexCoord2f32(0, 1); else GX_TexCoord2f32(1, 1); GX_Position3f32(-width, -height, 0); GX_Color4u8(255, 255, 255, 255); if( this->velx > 0 ) GX_TexCoord2f32(1, 1); else GX_TexCoord2f32(0, 1); GX_End(); }
/**************************************************************************** * ResetVideo_Menu * * Reset the video/rendering mode for the menu ****************************************************************************/ void ResetVideo_Menu() { Mtx44 p; f32 yscale; u32 xfbHeight; VIDEO_Configure (vmode); VIDEO_Flush(); VIDEO_WaitVSync(); if (vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); else while (VIDEO_GetNextField()) VIDEO_WaitVSync(); // clears the bg to color and clears the z buffer GXColor background = {0, 0, 0, 255}; GX_SetCopyClear (background, 0x00ffffff); yscale = GX_GetYScaleFactor(vmode->efbHeight,vmode->xfbHeight); xfbHeight = GX_SetDispCopyYScale(yscale); GX_SetScissor(0,0,vmode->fbWidth,vmode->efbHeight); GX_SetDispCopySrc(0,0,vmode->fbWidth,vmode->efbHeight); GX_SetDispCopyDst(vmode->fbWidth,xfbHeight); GX_SetCopyFilter(vmode->aa,vmode->sample_pattern,GX_TRUE,vmode->vfilter); GX_SetFieldMode(vmode->field_rendering,((vmode->viHeight==2*vmode->xfbHeight)?GX_ENABLE:GX_DISABLE)); if (vmode->aa) GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR); else GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); // setup the vertex descriptor // tells the flipper to expect direct data GX_ClearVtxDesc(); GX_InvVtxCache (); GX_InvalidateTexAll(); GX_SetVtxDesc(GX_VA_TEX0, GX_NONE); GX_SetVtxDesc(GX_VA_POS, 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_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetZMode (GX_FALSE, GX_LEQUAL, GX_TRUE); GX_SetNumChans(1); GX_SetNumTexGens(1); GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); guMtxIdentity(GXmodelView2D); guMtxTransApply (GXmodelView2D, GXmodelView2D, 0.0F, 0.0F, -200.0F); GX_LoadPosMtxImm(GXmodelView2D,GX_PNMTX0); guOrtho(p,0,479,0,639,0,300); GX_LoadProjectionMtx(p, GX_ORTHOGRAPHIC); GX_SetViewport(0,0,vmode->fbWidth,vmode->efbHeight,0,1); GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GX_SetAlphaUpdate(GX_TRUE); }
void Util3D::CameraIdentity() { GX_LoadPosMtxImm (Singleton<WiiManager>::GetInstanceByRef().GetCamera()->GetcameraMatrix(), GX_PNMTX0); }
//--------------------------------------------------------------------------------- int main( int argc, char **argv ){ //--------------------------------------------------------------------------------- u32 fb; // initial framebuffer index u32 first_frame; f32 yscale; u32 xfbHeight; Mtx44 perspective; Mtx GXmodelView2D; void *gp_fifo = NULL; GXColor background = {0, 0, 0, 0xff}; int i; VIDEO_Init(); rmode = VIDEO_GetPreferredMode(NULL); fb = 0; first_frame = 1; // allocate 2 framebuffers for double buffering frameBuffer[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); frameBuffer[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); VIDEO_Configure(rmode); VIDEO_SetNextFramebuffer(frameBuffer[fb]); VIDEO_SetBlack(FALSE); VIDEO_Flush(); VIDEO_WaitVSync(); if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); fb ^= 1; // setup the fifo and then init the flipper gp_fifo = memalign(32,DEFAULT_FIFO_SIZE); memset(gp_fifo,0,DEFAULT_FIFO_SIZE); GX_Init(gp_fifo,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 descriptor // tells the flipper to expect direct data GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetNumChans(1); GX_SetNumTexGens(1); GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GX_InvalidateTexAll(); TPLFile spriteTPL; TPL_OpenTPLFromMemory(&spriteTPL, (void *)textures_tpl,textures_tpl_size); TPL_GetTexture(&spriteTPL,ballsprites,&texObj); GX_LoadTexObj(&texObj, GX_TEXMAP0); guOrtho(perspective,0,479,0,639,0,300); GX_LoadProjectionMtx(perspective, GX_ORTHOGRAPHIC); PAD_Init(); srand(time(NULL)); for(i = 0; i < NUM_SPRITES; i++) { //random place and speed sprites[i].x = (rand() % (640 - 32 )) << 8; sprites[i].y = (rand() % (480 - 32 )) << 8 ; sprites[i].dx = (rand() & 0xFF) + 0x100; sprites[i].dy = (rand() & 0xFF) + 0x100; sprites[i].image = rand() & 3; if(rand() & 1) sprites[i].dx = -sprites[i].dx; if(rand() & 1) sprites[i].dy = -sprites[i].dy; } GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1); guMtxIdentity(GXmodelView2D); guMtxTransApply (GXmodelView2D, GXmodelView2D, 0.0F, 0.0F, -5.0F); GX_LoadPosMtxImm(GXmodelView2D,GX_PNMTX0); GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GX_SetAlphaUpdate(GX_TRUE); GX_SetColorUpdate(GX_TRUE); while(1) { PAD_ScanPads(); if (PAD_ButtonsDown(0) & PAD_BUTTON_START) exit(0); GX_InvVtxCache(); GX_InvalidateTexAll(); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); for(i = 0; i < NUM_SPRITES; i++) { sprites[i].x += sprites[i].dx; sprites[i].y += sprites[i].dy; //check for collision with the screen boundaries if(sprites[i].x < (1<<8) || sprites[i].x > ((640-32) << 8)) sprites[i].dx = -sprites[i].dx; if(sprites[i].y < (1<<8) || sprites[i].y > ((480-32) << 8)) sprites[i].dy = -sprites[i].dy; drawSpriteTex( sprites[i].x >> 8, sprites[i].y >> 8, 32, 32, sprites[i].image); } GX_DrawDone(); GX_CopyDisp(frameBuffer[fb],GX_TRUE); VIDEO_SetNextFramebuffer(frameBuffer[fb]); if(first_frame) { VIDEO_SetBlack(FALSE); first_frame = 0; } VIDEO_Flush(); VIDEO_WaitVSync(); fb ^= 1; // flip framebuffer } return 0; }
void glEnd(void) { GX_SetCullMode(GX_CULL_FRONT); Mtx mvi; Mtx mv; // Mtx inversemodelview; // load the modelview matrix into matrix memory guMtxConcat(view,model,modelview); GX_LoadPosMtxImm(modelview, GX_PNMTX0); //for normals first calculate normal matrix (thanks shagkur) guMtxInverse(modelview,mvi); guMtxTranspose(mvi,modelview); GX_LoadNrmMtxImm(modelview,GX_PNMTX0); //experimtal leave out (hmm works good?) //use global ambient light together with current material ambient and add emissive material color GXColor constcolor; constcolor.r = (gxcurrentmaterialambientcolor.r*gxglobalambientlightcolor.r) * 0xFF; constcolor.g = (gxcurrentmaterialambientcolor.g*gxglobalambientlightcolor.g) * 0xFF; constcolor.b = (gxcurrentmaterialambientcolor.b*gxglobalambientlightcolor.b) * 0xFF; constcolor.a = (gxcurrentmaterialambientcolor.a*gxglobalambientlightcolor.a) * 0xFF; GX_SetTevColor(GX_TEVREG0, constcolor); GXColor emiscolor; emiscolor.r = gxcurrentmaterialemissivecolor.r * 0xFF; emiscolor.g = gxcurrentmaterialemissivecolor.g * 0xFF; emiscolor.b = gxcurrentmaterialemissivecolor.b * 0xFF; emiscolor.a = gxcurrentmaterialemissivecolor.a * 0xFF; GX_SetTevColor(GX_TEVREG1, emiscolor); //first check if a lightdirtyflag is set (thanks ector) so we do not have to set up light every run //also usefull on matrices etc. //now set each light GXColor gxchanambient; gxchanambient.r = gxcurrentmaterialambientcolor.r; gxchanambient.g = gxcurrentmaterialambientcolor.g; gxchanambient.b = gxcurrentmaterialambientcolor.b; gxchanambient.a = gxcurrentmaterialambientcolor.a; GXColor gxchanspecular; gxchanspecular.r = gxcurrentmaterialspecularcolor.r; gxchanspecular.g = gxcurrentmaterialspecularcolor.g; gxchanspecular.b = gxcurrentmaterialspecularcolor.b; gxchanspecular.a = gxcurrentmaterialspecularcolor.a; int lightcounter = 0; for (lightcounter =0; lightcounter < 4; lightcounter++){ if(gxlightenabled[lightcounter]){ //when light is enabled //somewhere here an error happens? //Setup mat/light ambient color gxchanambient.r = ((gxchanambient.r * gxlightambientcolor[lightcounter].r) * 0xFF); gxchanambient.g = ((gxchanambient.g * gxlightambientcolor[lightcounter].g) * 0xFF); gxchanambient.b = ((gxchanambient.b * gxlightambientcolor[lightcounter].b) * 0xFF); gxchanambient.a = ((gxchanambient.a * gxlightambientcolor[lightcounter].a) * 0xFF); GX_SetChanAmbColor(GX_COLOR0A0, gxchanambient ); //Setup diffuse material color GXColor mdc; mdc.r = (gxcurrentmaterialdiffusecolor.r * 0xFF); mdc.g = (gxcurrentmaterialdiffusecolor.g * 0xFF); mdc.b = (gxcurrentmaterialdiffusecolor.b * 0xFF); mdc.a = (gxcurrentmaterialdiffusecolor.a * 0xFF); GX_SetChanMatColor(GX_COLOR0A0, mdc ); //Setup specular material color // gxcurrentmaterialshininess * gxchanspecular.r = (gxchanspecular.r * gxlightspecularcolor[lightcounter].r) * 0xFF; gxchanspecular.g = (gxchanspecular.g * gxlightspecularcolor[lightcounter].g) * 0xFF; gxchanspecular.b = (gxchanspecular.b * gxlightspecularcolor[lightcounter].b) * 0xFF; gxchanspecular.a = (gxchanspecular.a * gxlightspecularcolor[lightcounter].a) * 0xFF; GX_SetChanMatColor(GX_COLOR1A1, gxchanspecular); // use red as test color //Setup light diffuse color GXColor ldc; ldc.r = gxlightdiffusecolor[lightcounter].r * 0xFF; ldc.g = gxlightdiffusecolor[lightcounter].g * 0xFF; ldc.b = gxlightdiffusecolor[lightcounter].b * 0xFF; ldc.a = gxlightdiffusecolor[lightcounter].a * 0xFF; GX_InitLightColor(&gxlight[lightcounter], ldc ); //move call to glend or init?; GX_InitLightColor(&gxlight[lightcounter+4], ldc ); //move call to glend or init?; //Setup light postion //check on w component when 1. light is positional // when 0. light is directional at infinite pos guVector lpos; guVector wpos; lpos.x = gxlightpos[lightcounter].x; lpos.y = gxlightpos[lightcounter].y; lpos.z = gxlightpos[lightcounter].z; if (gxlightpos[lightcounter].w == 0){ guVecNormalize(&lpos); lpos.x *= BIG_NUMBER; lpos.y *= BIG_NUMBER; lpos.z *= BIG_NUMBER; } guVecMultiply(view,&lpos,&wpos); //light position should be transformed by world-to-view matrix (thanks h0lyRS) GX_InitLightPosv(&gxlight[lightcounter], &wpos); //feed corrected coord to light pos GX_InitLightPosv(&gxlight[lightcounter+4], &wpos); //feed corrected coord to light pos //Setup light direction (when w is 1 dan dir = 0,0,0 guVector ldir; if (gxlightpos[lightcounter].w==0){ //lpos.x = gxlightpos[lightcounter].x; //lpos.y = gxlightpos[lightcounter].y; //lpos.z = gxlightpos[lightcounter].z; ldir.x = gxlightpos[lightcounter].x; ldir.y = gxlightpos[lightcounter].y; ldir.z = gxlightpos[lightcounter].z; } else { if (gxspotcutoff[lightcounter] != 180){ //if we have a spot light direction is needed ldir.x = gxspotdirection[lightcounter].x; ldir.y = gxspotdirection[lightcounter].y; ldir.z = gxspotdirection[lightcounter].z; } else { ldir.x = 0; ldir.y = 0; ldir.z = -1; } } //guVecNormalize(&ldir); //ldir.x *= BIG_NUMBER; //ldir.y *= BIG_NUMBER; //ldir.z *= BIG_NUMBER; guMtxInverse(view,mvi); guMtxTranspose(mvi,view); guVecMultiply(view,&ldir,&ldir); //and direction should be transformed by inv-transposed of world-to-view (thanks h0lyRS) GX_InitLightDir(&gxlight[lightcounter], ldir.x, ldir.y, ldir.z); //feed corrected coord to light dir GX_InitLightDir(&gxlight[lightcounter+4], ldir.x, ldir.y, ldir.z); //feed corrected coord to light dir if (gxspotcutoff[lightcounter] != 180){ //Setup specular light (only for spotlight when GL_SPOT_CUTOFF <> 180) //make this line optional? If on it disturbs diffuse light? guVector sdir; sdir.x = gxspotdirection[lightcounter].x; sdir.y = gxspotdirection[lightcounter].y; sdir.z = gxspotdirection[lightcounter].z; //guVecNormalize(&sdir); //sdir.x *= BIG_NUMBER; //sdir.y *= BIG_NUMBER; //sdir.z *= BIG_NUMBER; guVecMultiply(view,&sdir,&sdir); guVector light_dir; guVecSub(&sdir, &lpos, &light_dir); GX_TestInitSpecularDir(&gxlight[lightcounter], light_dir.x, light_dir.y, light_dir.z); //needed to enable specular light GX_TestInitSpecularDir(&gxlight[lightcounter+4], light_dir.x, light_dir.y, light_dir.z); //needed to enable specular light }; //this calls: // #define GX_InitLightShininess(lobj, shininess) (GX_InitLightAttn(lobj, 0.0F, 0.0F, 1.0F, (shininess)/2.0F, 0.0F, 1.0F-(shininess)/2.0F )) //Setup distance attinuation (opengl vs gx differences?) //GX_InitLightDistAttn(&gxlight[lightcounter], 100.0f, gxspotexponent[lightcounter], GX_DA_GENTLE); //gxspotexponent was 0.5f //ref_dist, bright, dist func //k0 = 1.0; //k1 = 0.5f*(1.0f-ref_brite)/(ref_brite*ref_dist); //k2 = 0.5f*(1.0f-ref_brite)/(ref_brite*ref_dist*ref_dist); or 0.0f; //Attenuation factor = 1 / (kc + kl*d + kq*d2) //kc = constant attenuation factor (default = 1.0) //kl = linear attenuation factor (default = 0.0) //kq = quadratic attenuation factor (default = 0.0) float distance = BIG_NUMBER; //either distance of light or falloff factor float factor = 1 / (gxconstantattanuation[lightcounter] + gxlinearattanuation[lightcounter]*distance + gxquadraticattanuation[lightcounter]*distance*distance); //float factor = 5.0; //k0 - 0; //k1 = 0.5f*(1.0f-ref_brite)/(ref_brite*ref_dist); //k2 = 0.5f*(1.0f-ref_brite)/(ref_brite*ref_dist*ref_dist); /* GX_InitLightAttn(&gxlight[lightcounter], 1.0, //filled by initlightspot 0.0, //filled by initlightspot 0.0, //filled by initlightspot gxconstantattanuation[lightcounter], gxlinearattanuation[lightcounter]*distance, gxquadraticattanuation[lightcounter]*distance*distance ) ; // k0 k1 , k2 */ //GX_InitLightAttnK(&gxlight[lightcounter], (gxcurrentmaterialshininess)/2.0F , 0.0F ,1.0F-(gxcurrentmaterialshininess)/2.0F); GX_InitLightDistAttn(&gxlight[lightcounter], factor ,1.0, GX_DA_STEEP); //gxspotexponent[lightcounter] GX_DA_GENTLE GX_InitLightDistAttn(&gxlight[lightcounter+4], factor ,1.0, GX_DA_STEEP); //gxspotexponent[lightcounter] GX_DA_GENTLE //ref_dist //ref_brite // factor / strenght //1.0 is // glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 10.0f); ?? //Setup light type (normal/spotlight) //0-90 / 255-0 //cut_off, spot func //GX_InitLightSpot(&gxlight[lightcounter], 0.0f, GX_SP_OFF); //not this is not a spot light //GX_InitLightShininess(&gxlight[lightcounter], gxcurrentmaterialshininess); // /180? //float testspot = 90 - ((gxcurrentmaterialshininess * 90) / 128); //thanks ector 90 - (x * 90 / 255) //if (gxcurrentmaterialshininess == 0){ // testspot = 90; //} //zid 255-gxcurrentmaterialshininess/(255/90); //setup specular highlight //GX_InitLightSpot(&gxlight[lightcounter], testspot, GX_SP_COS); //not this is not a spot light (gxspotcutoff[lightcounter]) //setup normal spotlight GX_InitLightSpot(&gxlight[lightcounter], gxspotcutoff[lightcounter], GX_SP_RING1); //not this is not a spot light () GX_InitLightSpot(&gxlight[1], gxspotcutoff[lightcounter], GX_SP_RING1); //not this is not a spot light () if ( gxcurrentmaterialshininess != 0 ) { //if (gxspotcutoff[lightcounter] != 180) { GX_TestInitLightShininess(&gxlight[lightcounter+4], gxcurrentmaterialshininess); //} }; //Load the light up switch (lightcounter){ case 0: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT0); GX_LoadLightObj(&gxlight[lightcounter+4], GX_LIGHT4); break; case 1: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT1); GX_LoadLightObj(&gxlight[lightcounter+4], GX_LIGHT5); break; case 2: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT2); GX_LoadLightObj(&gxlight[lightcounter+4], GX_LIGHT6); break; case 3: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT3); GX_LoadLightObj(&gxlight[lightcounter+4], GX_LIGHT7); break; // case 4: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT4); break; // case 5: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT5); break; // case 6: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT6); break; // case 7: GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT7); break; } //GX_LoadLightObj(&gxlight[lightcounter], GX_LIGHT0); //GX_LoadLightObj(&gxlight[1], GX_LIGHT1); } } //set the curtexture if tex2denabled if (tex2denabled){ GX_LoadTexObj(&gxtextures[curtexture], GX_TEXMAP0); //TODO: make GX_TEXMAP0 dynamic for multitexturing }; //now we can draw the gx way (experiment try render in reverse ivm normals pointing the wrong way) int countelements = _numelements*2; if (gxcullfaceanabled==true){ countelements = _numelements; } GX_Begin(_type, GX_VTXFMT0, countelements); //dependend on culling setting int i =0; //default //order dependend on glFrontFace(GL_CCW); //or GL_CW // for( i=0; i<_numelements; i++) //GX_TRIANGLESTRIP GL_TRIANGLE_STRIP //0 1 2 0 1 2 //1 3 2 2 1 3 //2 3 4 2 3 4 //better think of a clever swapping routine //maybe then no need to invert normal for trianglestrip anymore //also GX_TRIANLES need to be drawn in reverse? //but GX_QUAD does not //so GX = CW by default while opengl is CCW by default? //bushing say cannot i be possibel that opengl reorders vertexes //u32 reverse = 0; //int pos = 0; //int temp = 0; //GL_POLYGON: http://www.gamedev.net/reference/articles/article425.asp bool cw = true; bool ccw = true; if(gxcullfaceanabled==true){ cw = false; ccw = false; switch(gxwinding){ case GL_CW: cw = true; break; case GL_CCW: ccw = true; break; } } if (cw==true){ //CW for( i=_numelements-1; i>=0; i--) { UploadVertex(i); } } if (ccw==true){ //CCW for( i=0; i<_numelements; i++) { UploadVertex(i); } } GX_End(); //clean up just to be sure i =0; for( i=0; i<_numelements; i++) { _vertexelements[i].x = 0.0F; _vertexelements[i].y = 0.0F; _vertexelements[i].z = 0.0F; _normalelements[i].x = 0.0F; _normalelements[i].y = 0.0F; _normalelements[i].z = 0.0F; _colorelements[i].r = 0.0F; _colorelements[i].g = 0.0F; _colorelements[i].b = 0.0F; _colorelements[i].a = 0.0F; _texcoordelements[i].s = 0.0F; _texcoordelements[i].t = 0.0F; } _numelements =0; }
void Particle_Render(Mtx M_view, ParticleSystem* psystem, Camera* camera) { // setup TEV 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_VTXFMT6, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT6, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GX_SetVtxAttrFmt(GX_VTXFMT6, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); // load model-view matrix Mtx M_modelView; guMtxIdentity(M_modelView); GX_LoadPosMtxImm(M_modelView, GX_PNMTX0); // setup tev GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GX_SetAlphaUpdate(GX_TRUE); GX_SetNumChans(1); GX_SetTevColorIn( GX_TEVSTAGE0, GX_CC_TEXC, // a GX_CC_RASC, // b GX_CC_TEXA, // c GX_CC_ZERO); // d GX_SetTevColorOp( GX_TEVSTAGE0, // stage GX_TEV_ADD, // op GX_TB_ZERO, // bias GX_CS_SCALE_2, // scale GX_ENABLE, // clamp 0-255 GX_TEVPREV); // output reg GX_SetTevAlphaIn( GX_TEVSTAGE0, GX_CA_ZERO, // a GX_CA_TEXA, // b GX_CA_RASA, // c GX_CA_ZERO); // d GX_SetTevAlphaOp( GX_TEVSTAGE0, // stage GX_TEV_ADD, // op GX_TB_ZERO, // bias GX_CS_SCALE_1, // scale GX_ENABLE, // clamp 0-255 GX_TEVPREV); // output reg GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GX_SetNumTexGens(1); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GX_LoadTexObj(&psystem->texture, GX_TEXMAP0); int n = psystem->n_particles; f32 texCoords[] = { 0, 0, 0, 1, 1, 1, 1, 0 }; GX_InvVtxCache(); Vec3 camPos = camera->position(); Mtx axisMtx; System::LogClear(); Particle_Sort(M_view, psystem); GX_Begin(GX_QUADS, GX_VTXFMT6, n*4); for (int k = 0; k < n; k++) { int i = psystem->binsAllocations[k].particleIdx; //System::Log(L"p%d", i); Vec3& p = psystem->positions[i]; f32 lifetime = psystem->lifetimes[i]; f32 age = psystem->ages[i]; f32 ratio = age/lifetime; Vec3 forward = Math3D::normalized(camPos - p); Vec3 worldUp = Vec3(0, 1, 0); Vec3 right = Math3D::normalized(Math3D::cross(worldUp, forward)); Vec3 up = Math3D::cross(forward, right); Mtx pm; guMtxCopy(M_view, pm); guMtxTranspose(pm, pm); pm[0][3] = p.x; pm[1][3] = p.y; pm[2][3] = p.z; guMtxConcat(M_view, pm, pm); f32 rotation = psystem->rotations[i]; if (psystem->rotationInterpolator) rotation = psystem->rotationInterpolator->getValue(rotation, ratio); f32 size = psystem->sizes[i]; if (psystem->sizeInterpolator) size = psystem->sizeInterpolator->getValue(size, ratio); if (psystem->colorInterpolator) psystem->colors[i] = psystem->colorInterpolator->getValue(ratio); Matrix34 M_rot = Math3D::matrixRotationZ(rotation); f32 hs = size*0.5f; Vec3 p0(-hs, +hs, 0); Vec3 p1(-hs, -hs, 0); Vec3 p2(+hs, -hs, 0); Vec3 p3(+hs, +hs, 0); Vec3 vs[4] = {p0, p1, p2, p3}; for (int i = 0; i < 4; i++) { vs[i] = M_rot * vs[i]; vs[i] = Math3D::matrixVecMul(pm, vs[i]); } for (int i = 0; i < 4; i++) { f32* coords = &texCoords[2*i]; SendVertex(vs[i], psystem->colors[i], coords[0], coords[1]); } } GX_End(); return; }
void WiiPointer::Draw(GuiTrigger *t) { if(t && pointerImg) { if(t->wpad.ir.valid) { lastActivity = 0; posX = t->wpad.ir.x; posY = t->wpad.ir.y; angle = t->wpad.ir.angle; } else { angle = 0.0f; // GC PAD // x-axis if(t->pad.stickX < -PADCAL) { posX += (t->pad.stickX + PADCAL) * Settings.PointerSpeed; lastActivity = 0; } else if(t->pad.stickX > PADCAL) { posX += (t->pad.stickX - PADCAL) * Settings.PointerSpeed; lastActivity = 0; } // y-axis if(t->pad.stickY < -PADCAL) { posY -= (t->pad.stickY + PADCAL) * Settings.PointerSpeed; lastActivity = 0; } else if(t->pad.stickY > PADCAL) { posY -= (t->pad.stickY - PADCAL) * Settings.PointerSpeed; lastActivity = 0; } //Wii u pro x-axis if(t->wupcdata.stickX < -WUPCCAL) { posX += (t->wupcdata.stickX + WUPCCAL) * Settings.PointerSpeed/8; lastActivity = 0; } else if(t->wupcdata.stickX > WUPCCAL) { posX += (t->wupcdata.stickX - WUPCCAL) * Settings.PointerSpeed/8; lastActivity = 0; } //Wii u pro y-axis if(t->wupcdata.stickY < -WUPCCAL) { posY -= (t->wupcdata.stickY + WUPCCAL) * Settings.PointerSpeed/8; lastActivity = 0; } else if(t->wupcdata.stickY > WUPCCAL) { posY -= (t->wupcdata.stickY - WUPCCAL) * Settings.PointerSpeed/8; lastActivity = 0; } int wpadX = t->WPAD_Stick(0, 0); int wpadY = t->WPAD_Stick(0, 1); // Wii Extensions // x-axis if(wpadX < -PADCAL) { posX += (wpadX + PADCAL) * Settings.PointerSpeed; lastActivity = 0; } else if(wpadX > PADCAL) { posX += (wpadX - PADCAL) * Settings.PointerSpeed; lastActivity = 0; } // y-axis if(wpadY < -PADCAL) { posY -= (wpadY + PADCAL) * Settings.PointerSpeed; lastActivity = 0; } else if(wpadY > PADCAL) { posY -= (wpadY - PADCAL) * Settings.PointerSpeed; lastActivity = 0; } if(t->pad.btns_h || t->wpad.btns_h || t->wupcdata.btns_h) lastActivity = 0; posX = LIMIT(posX, -50.0f, screenwidth+50.0f); posY = LIMIT(posY, -50.0f, screenheight+50.0f); if(lastActivity < 2) { // (3s on 60Hz and 3.6s on 50Hz) t->wpad.ir.valid = 1; t->wpad.ir.x = posX; t->wpad.ir.y = posY; } } if(t->wpad.ir.valid) { GXTexObj texObj; GX_InitTexObj(&texObj, pointerImg->GetImage(), pointerImg->GetWidth(), pointerImg->GetHeight(), GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_LoadTexObj(&texObj, GX_TEXMAP0); GX_ClearVtxDesc(); GX_InvVtxCache(); GX_InvalidateTexAll(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); Mtx mv; guMtxIdentity(mv); guMtxRotDeg (mv, 'z', angle); guMtxTransApply(mv, mv, posX, posY, 9900.f); guMtxConcat(FSModelView2D, mv, mv); GX_LoadProjectionMtx(projection, GX_ORTHOGRAPHIC); GX_LoadPosMtxImm(mv, GX_PNMTX0); // pointer is pointing to center of the texture f32 width = 0.5f * pointerImg->GetWidth(); f32 height = 0.5f * pointerImg->GetHeight(); GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position3f32(-width, -height, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, 0xFF); GX_TexCoord2f32(0, 0); GX_Position3f32(width, -height, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, 0xFF); GX_TexCoord2f32(1, 0); GX_Position3f32(width, height, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, 0xFF); GX_TexCoord2f32(1, 1); GX_Position3f32(-width, height, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, 0xFF); GX_TexCoord2f32(0, 1); GX_End(); } } ++lastActivity; }
/* * GX render callback */ void wii_render_callback() { GX_SetVtxDesc( GX_VA_POS, GX_DIRECT ); GX_SetVtxDesc( GX_VA_CLR0, GX_DIRECT ); GX_SetVtxDesc( GX_VA_TEX0, GX_NONE ); Mtx m; // model matrix. Mtx mv; // modelview matrix. guMtxIdentity( m ); guMtxTransApply( m, m, 0, 0, -100 ); guMtxConcat( gx_view, m, mv ); GX_LoadPosMtxImm( mv, GX_PNMTX0 ); // Diff switches wii_atari_display_diff_switches(); // // Debug // static int dbg_count = 0; if( wii_debug && !wii_testframe ) { static char text[256] = ""; static char text2[256] = ""; dbg_count++; if( dbg_count % 60 == 0 ) { /* a: %d, %d, c: 0x%x,0x%x,0x%x*/ /* wii_sound_length, wii_convert_length, memory_ram[CTLSWB], riot_drb, memory_ram[SWCHB] */ sprintf( text, "v: %.2f, hs: %d, %d, timer: %d, wsync: %s, %d, stl: %s, mar: %d, cpu: %d, ext: %d, rnd: %d, hb: %d", wii_fps_counter, high_score_set, hs_sram_write_count, ( riot_timer_count % 1000 ), ( dbg_wsync ? "1" : "0" ), dbg_wsync_count, ( dbg_cycle_stealing ? "1" : "0" ), dbg_maria_cycles, dbg_p6502_cycles, dbg_saved_cycles, RANDOM, cartridge_hblank ); } //sprintf( text, "video: %.2f", wii_fps_counter ); wii_gx_drawtext( -310, 210, 14, text, ftgxWhite, 0 ); if( lightgun_enabled ) { //ir_t ir; //WPAD_IR(WPAD_CHAN_0, &ir); sprintf( text2, "lightgun: %d, %d, %d, %.2f, %d, [%d, %d]", /*"lightgun: %d, %d, %d, %.2f, %d, [%d, %d] %d, %d, %d, %d", */ cartridge_crosshair_x, cartridge_crosshair_y, lightgun_scanline, lightgun_cycle, wii_dbg_scanlines, wii_ir_x, wii_ir_y /*, ir.vres[0], ir.vres[1], ir.offset[0], ir.offset[1]*/ ); wii_gx_drawtext( -310, -210, 14, text2, ftgxWhite, 0 ); } } }
void Textbox::Draw(const BannerResources& resources, u8 parent_alpha, const float ws_scale, Mtx &modelview) const { if(!text) return; if(header->font_index >= resources.fonts.size()) return; WiiFont *font = resources.fonts[header->font_index]; if(!font->IsLoaded()) return; // Ugly...but doing it by going through all panes is more ugly // TODO: move it to somewhere else if(lineWidths.empty()) ((Textbox *) this)->SetTextWidth(font); if(lineWidths.empty()) return; SetupGX(resources); GX_LoadPosMtxImm(modelview, GX_PNMTX0); // Setup text color GXColor color0 = { header->color[0].r, header->color[0].g, header->color[0].b, MultiplyAlpha(header->color[0].a, parent_alpha) }; GXColor color1 = { header->color[1].r, header->color[1].g, header->color[1].b, MultiplyAlpha(header->color[1].a, parent_alpha) }; u32 lastSheetIdx = 0xffff; float scale = header->font_size /(float)font->CharacterHeight(); // use complete text width if not aligned to middle float textWidth = (GetAlignHor() == 1) ? lineWidths[0] : frameWidth; // position offset calculation for first line...why the hell is it that complex? float xPos = -0.5f * ( GetOriginX() * GetWidth() * ws_scale + GetAlignHor() * (-GetWidth() * ws_scale + textWidth) ); float yPos = -0.5f * ( GetAlignVer() * -frameHeight + GetHeight() * (GetAlignVer() - (2 - GetOriginY())) ) - header->font_size; // store the character width here for later use, it's constant over the text float charWidth = scale * (float)font->CharacterWidth(); int lineNumber = 0; for(const u16 *txtString = text; *txtString != 0; txtString++) { if(*txtString == '\n') { lineNumber++; // use complete text width if not aligned to middle textWidth = (GetAlignHor() == 1) ? lineWidths[lineNumber] : frameWidth; // calculate text position depending on line width xPos = -0.5f * (GetOriginX() * GetWidth() * ws_scale + GetAlignHor() * (-GetWidth() * ws_scale + textWidth)); // go one line down yPos -= (header->font_size + header->space_line); continue; } const WiiFont::CharInfo *charInfo = font->GetCharInfo(*txtString); if(!charInfo) continue; if(charInfo->sheetIdx != lastSheetIdx) { lastSheetIdx = charInfo->sheetIdx; if(!font->Apply(charInfo->sheetIdx)) continue; } if(charInfo->unk) xPos += scale * (float)charInfo->advanceKerning; GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position3f32(xPos, yPos, 0.f); GX_Color4u8(color1.r, color1.g, color1.b, color1.a); GX_TexCoord2f32(charInfo->s1, charInfo->t2); GX_Position3f32(xPos + charWidth, yPos, 0.f); GX_Color4u8(color1.r, color1.g, color1.b, color1.a); GX_TexCoord2f32(charInfo->s2, charInfo->t2); GX_Position3f32(xPos + charWidth, yPos + header->font_size, 0.f); GX_Color4u8(color0.r, color0.g, color0.b, color0.a); GX_TexCoord2f32(charInfo->s2, charInfo->t1); GX_Position3f32(xPos, yPos + header->font_size, 0.f); GX_Color4u8(color0.r, color0.g, color0.b, color0.a); GX_TexCoord2f32(charInfo->s1, charInfo->t1); GX_End(); xPos += scale * (float)charInfo->advanceGlyphX; } }
static int drawgx_window_create(sdl_window_info *window, int width, int height) { sdl_info *sdl = window->dxdata; u32 xfbHeight; f32 yscale; Mtx44 perspective; Mtx GXmodelView2D; GXColor background = {0, 0, 0, 0xff}; currfb = 0; // allocate memory for our structures sdl = malloc(sizeof(*sdl)); memset(sdl, 0, sizeof(*sdl)); window->dxdata = sdl; sdl->scale_mode = &scale_modes[window->scale_mode]; sdl->extra_flags = (window->fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE); sdl->extra_flags |= sdl->scale_mode->extra_flags; /*sdl->sdlsurf = SDL_SetVideoMode(width, height, 0, SDL_SWSURFACE | SDL_ANYFORMAT | sdl->extra_flags);*/ //sdl->sdlsurf = SDL_SetVideoMode(640, 480, 32, SDL_DOUBLEBUF); //if (!sdl->sdlsurf) // return 1; window->width = gx_screenWidth();//sdl->sdlsurf->w; window->height = 480;//sdl->sdlsurf->h; sdl->safe_hofs = (window->width - window->width * options_get_float(mame_options(), SDLOPTVAL_SAFEAREA)) / 2; sdl->safe_vofs = (window->height - window->height * options_get_float(mame_options(), SDLOPTVAL_SAFEAREA)) / 2; /*if (sdl->scale_mode->is_yuv) yuv_overlay_init(window);*/ sdl->yuv_lookup = NULL; sdl->blittimer = 0; //if (is_inited) return 0; //is_inited = 1; //drawgx_yuv_init(sdl); //SDL_QuitSubSystem(SDL_INIT_VIDEO); if (is_inited) return 0; is_inited = 1; VIDEO_Init(); VIDEO_SetBlack(true); vmode = VIDEO_GetPreferredMode(NULL); switch (vmode->viTVMode >> 2) { case VI_PAL: vmode = &TVPal574IntDfScale; vmode->xfbHeight = 480; vmode->viYOrigin = (VI_MAX_HEIGHT_PAL - 480)/2; vmode->viHeight = 480; break; case VI_NTSC: break; default: break; } VIDEO_Configure(vmode); xfb[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode)); xfb[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode)); VIDEO_ClearFrameBuffer(vmode, xfb[0], COLOR_BLACK); VIDEO_ClearFrameBuffer(vmode, xfb[1], COLOR_BLACK); VIDEO_SetNextFramebuffer(xfb[currfb]); VIDEO_Flush(); VIDEO_WaitVSync(); if (vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); else while (VIDEO_GetNextField()) VIDEO_WaitVSync(); gp_fifo = memalign(32, DEFAULT_FIFO_SIZE); memset(gp_fifo, 0, DEFAULT_FIFO_SIZE); GX_Init(gp_fifo, DEFAULT_FIFO_SIZE); atexit(drawgx_shutdown); GX_SetCopyClear(background, 0x00ffffff); // other gx setup GX_SetViewport(0,0,vmode->fbWidth,vmode->efbHeight,0,1); yscale = GX_GetYScaleFactor(vmode->efbHeight,vmode->xfbHeight); xfbHeight = GX_SetDispCopyYScale(yscale); GX_SetScissor(0,0,vmode->fbWidth,vmode->efbHeight); GX_SetDispCopySrc(0,0,vmode->fbWidth,vmode->efbHeight); GX_SetDispCopyDst(vmode->fbWidth,xfbHeight); GX_SetCopyFilter(vmode->aa,vmode->sample_pattern,GX_TRUE,vmode->vfilter); GX_SetFieldMode(vmode->field_rendering,((vmode->viHeight==2*vmode->xfbHeight)?GX_ENABLE:GX_DISABLE)); if (vmode->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(xfb[currfb],GX_TRUE); GX_SetDispCopyGamma(GX_GM_1_0); GX_SetNumChans(1); GX_SetNumTexGens(1); GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GX_SetAlphaUpdate(GX_TRUE); GX_SetColorUpdate(GX_TRUE); guOrtho(perspective,0,479,0,gx_screenWidth()-1,0,300); GX_LoadProjectionMtx(perspective, GX_ORTHOGRAPHIC); guMtxIdentity(GXmodelView2D); guMtxTransApply (GXmodelView2D, GXmodelView2D, 0.0F, 0.0F, -5.0F); GX_LoadPosMtxImm(GXmodelView2D,GX_PNMTX0); GX_SetViewport(0,0,vmode->fbWidth,vmode->efbHeight,0,1); GX_InvVtxCache(); GX_ClearVtxDesc(); GX_InvalidateTexAll(); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, 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_RGBA8, 0); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); VIDEO_SetBlack(false); GX_InitTexObj(&blankTex, blanktex, 1, 1, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE); return 0; }
void DrawOBB(Mtx M_view, OBB& box, u32 color, bool drawAxes) { //for (int i = 0; i < 3; i++) //SYS_LOG(L"u%i={%.3f, %.3f, %.3f}", i, box.u[i].x, box.u[i].y, box.u[i].z); //SYS_LOG(L"color=%x", color); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxAttrFmt(GX_VTXFMT5, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT5, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); // build and load model-view matrix Mtx M_modelView; guMtxIdentity(M_modelView); // rotation M_modelView[0][0] = box.u[0].x; M_modelView[0][1] = box.u[0].y; M_modelView[0][2] = box.u[0].z; M_modelView[1][0] = box.u[1].x; M_modelView[1][1] = box.u[1].y; M_modelView[1][2] = box.u[1].z; M_modelView[2][0] = box.u[2].x; M_modelView[2][1] = box.u[2].y; M_modelView[2][2] = box.u[2].z; // translation M_modelView[0][3] = box.c.x; M_modelView[1][3] = box.c.y; M_modelView[2][3] = box.c.z; guMtxConcat(M_view, M_modelView, M_modelView); GX_LoadPosMtxImm(M_modelView, GX_PNMTX0); GX_SetNumChans(1); // default, color = vertex color //GX_SetNumTexGens(0); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); u8 indices[8] = {0, 1, 0, 2, 1, 3, 2, 3}; f32* e = box.e; guVector v_bottom[4]; v_bottom[0] = _vec(-e[0], -e[1], +e[2]); v_bottom[1] = _vec(+e[0], -e[1], +e[2]); v_bottom[2] = _vec(-e[0], -e[1], -e[2]); v_bottom[3] = _vec(+e[0], -e[1], -e[2]); guVector v_top[4]; for (int i = 0; i < 4; i++) v_top[i] = _vec(v_bottom[i].x, e[1], v_bottom[i].z); GX_Begin(GX_LINES, GX_VTXFMT5, 24); // draw bottom for (u8 i = 0; i < 8; i += 2) { guVector& v0 = v_bottom[indices[i]]; guVector& v1 = v_bottom[indices[i+1]]; SendVertex(v0, color); SendVertex(v1, color); } // draw top for (u8 i = 0; i < 8; i += 2) { guVector& v0 = v_top[indices[i]]; guVector& v1 = v_top[indices[i+1]]; SendVertex(v0, color); SendVertex(v1, color); } // connect bottom vertices with the top ones for (u8 i = 0; i < 4; i++) { guVector& v0 = v_bottom[i]; guVector& v1 = v_top[i]; SendVertex(v0, color); SendVertex(v1, color); } GX_End(); if (!drawAxes) return; // axes const f32 len = 150; GX_Begin(GX_LINES, GX_VTXFMT5, 6); guVector zero = {0, 0, 0}; guVector x_unit = {len, 0, 0}; guVector y_unit = {0, len, 0}; guVector z_unit = {0, 0, len}; color = 0xFF0000FF; SendVertex(zero, color); SendVertex(x_unit, color); color = 0x00FF00FF; SendVertex(zero, color); SendVertex(y_unit, color); color = 0x0000FFFF; SendVertex(zero, color); SendVertex(z_unit, color); GX_End(); }
void DrawAABB(MtxP M_model, Mtx M_view, AABB& box, u32 color) { GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxAttrFmt(GX_VTXFMT5, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT5, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); // build and load model-view matrix Mtx M_modelView; guMtxIdentity(M_modelView); guMtxConcat(M_view, M_model, M_modelView); GX_LoadPosMtxImm(M_modelView, GX_PNMTX0); GX_SetNumChans(1); // default, color = vertex color //GX_SetNumTexGens(0); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); u8 indices[8] = {0, 1, 0, 2, 1, 3, 2, 3}; guVector& m = box.min; f32* d = box.d; guVector v_bottom[4]; v_bottom[0] = _vec(m.x, m.y, m.z); v_bottom[1] = _vec(m.x + d[0], m.y, m.z); v_bottom[2] = _vec(m.x, m.y, m.z + d[2]); v_bottom[3] = _vec(m.x + d[0], m.y, m.z + d[2]); guVector v_top[4]; for (int i = 0; i < 4; i++) v_top[i] = _vec(v_bottom[i].x, v_bottom[i].y + d[1], v_bottom[i].z); GX_Begin(GX_LINES, GX_VTXFMT5, 24); // draw bottom for (u8 i = 0; i < 8; i += 2) { guVector& v0 = v_bottom[indices[i]]; guVector& v1 = v_bottom[indices[i+1]]; SendVertex(v0, color); SendVertex(v1, color); } // draw top for (u8 i = 0; i < 8; i += 2) { guVector& v0 = v_top[indices[i]]; guVector& v1 = v_top[indices[i+1]]; SendVertex(v0, color); SendVertex(v1, color); } // connect bottom vertices with the top ones for (u8 i = 0; i < 4; i++) { guVector& v0 = v_bottom[i]; guVector& v1 = v_top[i]; SendVertex(v0, color); SendVertex(v1, color); } GX_End(); }
void BoxCover::Draw() { u8 BoxAlpha = (int) (alpha+alphaDyn) & 0xFF; GX_LoadProjectionMtx(projection, GX_PERSPECTIVE); GX_ClearVtxDesc(); GX_InvVtxCache(); GX_SetVtxDesc(GX_VA_POS, GX_INDEX8); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX8); //! don't draw inside of the box GX_SetCullMode(GX_CULL_FRONT); Mtx modelView; Mtx modelView2; Mtx modelView3; guVector cubeAxis = {0,0,1}; guVector cubeAxis2 = {0,1,0}; guVector cubeAxis3 = {1,0,0}; guMtxIdentity(modelView); guMtxRotAxisDeg(modelView3, &cubeAxis3, RotX-Animation2); guMtxRotAxisDeg(modelView2, &cubeAxis2, RotY+Animation2+xoffsetDyn/2.0f); guMtxRotAxisDeg(modelView, &cubeAxis, RotZ-Animation); guMtxConcat(modelView3, modelView2, modelView2); guMtxConcat(modelView2, modelView, modelView); if(Settings.widescreen) guMtxScaleApply(modelView, modelView, Settings.WSFactor, 1.0f, 1.0f); guMtxTransApply(modelView, modelView, PosX+xoffsetDyn/680.0f+movePosX, PosY+yoffsetDyn/680.0f+movePosY, PosZ); guMtxConcat(view,modelView,modelView); GX_LoadPosMtxImm(modelView, GX_PNMTX0); //! Border quads GX_LoadTexObj(&boxBorderTex, GX_TEXMAP0); GX_InvalidateTexAll(); GX_SetArray(GX_VA_POS, (void *) &g_boxMeshQ[0].pos, sizeof(g_boxMeshQ[0])); GX_SetArray(GX_VA_TEX0, (void *) &g_boxMeshQ[0].texCoord, sizeof(g_boxMeshQ[0])); GX_Begin(GX_QUADS, GX_VTXFMT0, g_boxMeshQSize); for (u32 j = 0; j < g_boxMeshQSize; ++j) { GX_Position1x8(j); GX_Color4u8(boxColor.r, boxColor.g, boxColor.b, BoxAlpha); GX_TexCoord1x8(j); } GX_End(); //! Border triangles GX_SetArray(GX_VA_POS, (void *) &g_boxMeshT[0].pos, sizeof(g_boxMeshT[0])); GX_SetArray(GX_VA_TEX0, (void *) &g_boxMeshT[0].texCoord, sizeof(g_boxMeshT[0])); GX_Begin(GX_TRIANGLES, GX_VTXFMT0, g_boxMeshTSize); for (u32 j = 0; j < g_boxMeshTSize; ++j) { GX_Position1x8(j); GX_Color4u8(boxColor.r, boxColor.g, boxColor.b, BoxAlpha); GX_TexCoord1x8(j); } GX_End(); //! Back Cover (Might be flat) GX_LoadTexObj(flatCover ? &defaultBoxTex : &coverTex, GX_TEXMAP0); GX_InvalidateTexAll(); GX_SetArray(GX_VA_POS, (void *) &g_boxBackCoverMesh[0].pos, sizeof(g_boxBackCoverMesh[0])); GX_SetArray(GX_VA_TEX0, (void *) &g_boxBackCoverMesh[0].texCoord, sizeof(g_boxBackCoverMesh[0])); GX_Begin(GX_QUADS, GX_VTXFMT0, g_boxBackCoverMeshSize); for (u32 j = 0; j < g_boxBackCoverMeshSize; ++j) { GX_Position1x8(j); if(flatCover) GX_Color4u8(boxColor.r, boxColor.g, boxColor.b, BoxAlpha); else GX_Color4u8(0xff, 0xff, 0xff, BoxAlpha); GX_TexCoord1x8(j); } GX_End(); if(flatCover) { //! Front Flat Cover GX_LoadTexObj(&coverTex, GX_TEXMAP0); GX_InvalidateTexAll(); GX_SetArray(GX_VA_POS, (void *) &g_flatCoverMesh[0].pos, sizeof(g_flatCoverMesh[0])); GX_SetArray(GX_VA_TEX0, (void *) &g_flatCoverMesh[0].texCoord, sizeof(g_flatCoverMesh[0])); GX_Begin(GX_QUADS, GX_VTXFMT0, g_flatCoverMeshSize); for (u32 j = 0; j < g_flatCoverMeshSize; ++j) { GX_Position1x8(j); GX_Color4u8(0xff, 0xff, 0xff, 0xff); GX_TexCoord1x8(j); } GX_End(); } else { //! Front Cover GX_SetArray(GX_VA_POS, (void *) &g_boxCoverMesh[0].pos, sizeof(g_boxCoverMesh[0])); GX_SetArray(GX_VA_TEX0, (void *) &g_boxCoverMesh[0].texCoord, sizeof(g_boxCoverMesh[0])); GX_Begin(GX_QUADS, GX_VTXFMT0, g_boxCoverMeshSize); for (u32 j = 0; j < g_boxCoverMeshSize; ++j) { GX_Position1x8(j); GX_Color4u8(0xff, 0xff, 0xff, BoxAlpha); GX_TexCoord1x8(j); } GX_End(); } //! stop cull GX_SetCullMode(GX_CULL_NONE); UpdateEffects(); }
int main(int argc,char **argv) { f32 yscale,zt = 0; u32 xfbHeight; u32 fb = 0; f32 rquad = 0.0f; u32 first_frame = 1; GXTexObj texture; 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 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. 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_InvVtxCache(); GX_InvalidateTexAll(); TPL_OpenTPLFromMemory(&crateTPL, (void *)crate_tpl,crate_tpl_size); TPL_GetTexture(&crateTPL,crate,&texture); // 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); else if (WPAD_ButtonsHeld(0)&WPAD_BUTTON_UP) zt -= 0.25f; else if (WPAD_ButtonsHeld(0)&WPAD_BUTTON_DOWN) zt += 0.25f; // set number of rasterized color channels GX_SetNumChans(1); //set number of textures to generate GX_SetNumTexGens(1); // setup texture coordinate generation // args: texcoord slot 0-7, matrix type, source to generate texture coordinates from, matrix to use GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GX_SetTevOp(GX_TEVSTAGE0,GX_REPLACE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GX_LoadTexObj(&texture, GX_TEXMAP0); guMtxIdentity(model); guMtxRotAxisDeg(model, &cubeAxis, rquad); guMtxTransApply(model, model, 0.0f,0.0f,zt-7.0f); guMtxConcat(view,model,modelview); // load the modelview matrix into matrix memory GX_LoadPosMtxImm(modelview, GX_PNMTX3); GX_SetCurrentMtx(GX_PNMTX3); 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 ) } }
void Menu_DrawDiskCover(f32 xpos, f32 ypos, f32 zpos, u16 width, u16 height, u16 distance, u8 data[], f32 deg_alpha, f32 deg_beta, f32 scaleX, f32 scaleY, u8 alpha, bool shadow) { if (data == NULL) return; GX_LoadProjectionMtx(FSProjection2D, GX_ORTHOGRAPHIC); GXTexObj texObj; GX_InitTexObj(&texObj, data, width, height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_LoadTexObj(&texObj, GX_TEXMAP0); GX_ClearVtxDesc(); GX_InvVtxCache(); GX_InvalidateTexAll(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); f32 cos_beta = cos(DegToRad( deg_beta )); f32 s_offset_y = (zpos + (cos_beta * distance)) * tan(DegToRad( 5 )); f32 s_offset_x = (cos_beta < 0 ? -cos_beta : cos_beta) * s_offset_y; f32 s_offset_z = (s_offset_y < 0 ? 0 : s_offset_y) * 2; Mtx m, m1, m2, m3, m4, mv; width *= .5; height *= .5; guMtxIdentity(m4); guMtxTransApply(m4, m4, 0, 0, distance); guMtxIdentity(m1); guMtxScaleApply(m1, m1, scaleX, scaleY, 1.0); guVector axis2 = (guVector) {0 , 1, 0}; guMtxRotAxisDeg ( m2, &axis2, deg_beta ); guVector axis = (guVector) {0 , 0, 1}; guMtxRotAxisDeg ( m3, &axis, deg_alpha ); guMtxConcat(m3, m4, m3); // move distance then rotate z-axis guMtxConcat(m2, m3, m2); // rotate y-axis guMtxConcat(m1, m2, m); // scale if (shadow) guMtxTransApply(m, m, xpos + width + 0.5 + s_offset_x, ypos + height + 0.5 + s_offset_y, zpos - s_offset_z); else guMtxTransApply(m, m, xpos + width + 0.5, ypos + height + 0.5, zpos); guMtxConcat(FSModelView2D, m, mv); GX_LoadPosMtxImm(mv, GX_PNMTX0); GX_Begin(GX_QUADS, GX_VTXFMT0, 4); if (shadow) { GX_Position3f32(-width, -height, 0); GX_Color4u8(0, 0, 0, alpha); GX_TexCoord2f32(0, 0); GX_Position3f32(width, -height, 0); GX_Color4u8(0, 0, 0, alpha); GX_TexCoord2f32(1, 0); GX_Position3f32(width, height, 0); GX_Color4u8(0, 0, 0, alpha); GX_TexCoord2f32(1, 1); GX_Position3f32(-width, height, 0); GX_Color4u8(0, 0, 0, alpha); GX_TexCoord2f32(0, 1); } else { GX_Position3f32(-width, -height, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, alpha); GX_TexCoord2f32(0, 0); GX_Position3f32(width, -height, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, alpha); GX_TexCoord2f32(1, 0); GX_Position3f32(width, height, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, alpha); GX_TexCoord2f32(1, 1); GX_Position3f32(-width, height, 0); GX_Color4u8(0xFF, 0xFF, 0xFF, alpha); GX_TexCoord2f32(0, 1); } GX_End(); }