void MFParticleSystem_DrawRotating(MFParticleSystem *pParticleSystem, const MFMatrix <v) { int numParticles = pParticleSystem->particles.GetLength(); if(!numParticles) return; float fadeStart = pParticleSystem->params.life - pParticleSystem->params.fadeDelay; MFMaterial_SetMaterial(pParticleSystem->pMaterial); MFPrimitive(PT_TriList, 0); MFBegin(numParticles * 6); MFParticle **ppI = pParticleSystem->particles.Begin(); while(*ppI) { MFParticle *pParticle = *ppI; float dt = MFSystem_TimeDelta(); pParticle->rot += pParticleSystem->params.rotationRate * dt; pParticle->size += pParticleSystem->params.scaleRate * dt; pParticle->velocity += pParticleSystem->params.force * dt; pParticle->pos += pParticle->velocity * dt; float t = pParticle->size * 0.5f; float rad = MFSqrt(t*t*2); float xoff = MFCos(-pParticle->rot + 0.7853981f)*rad; float yoff = MFSin(-pParticle->rot + 0.7853981f)*rad; float alpha = MFMin(pParticle->life / fadeStart, 1.0f); MFVector pos = ApplyMatrixH(pParticle->pos, ltv); MFSetColourV(MakeVector(pParticle->colour, pParticle->colour.w * alpha)); MFSetTexCoord1(1, 0); MFSetPosition(pos.x + xoff, pos.y + yoff, pos.z); MFSetTexCoord1(0, 1); MFSetPosition(pos.x - xoff, pos.y - yoff, pos.z); MFSetTexCoord1(0, 0); MFSetPosition(pos.x - yoff, pos.y + xoff, pos.z); MFSetTexCoord1(1, 0); MFSetPosition(pos.x + xoff, pos.y + yoff, pos.z); MFSetTexCoord1(1, 1); MFSetPosition(pos.x + yoff, pos.y - xoff, pos.z); MFSetTexCoord1(0, 1); MFSetPosition(pos.x - xoff, pos.y - yoff, pos.z); pParticle->life -= dt; if(pParticle->life < 0.0f) pParticleSystem->particles.Destroy(ppI); ppI++; } MFEnd(); }
MF_API void MFPrimitive(uint32 type, uint32 hint) { MFCALLSTACK; primType = type & PT_PrimMask; if(type & PT_Untextured) { MFMaterial_SetMaterial(MFMaterial_GetStockMaterial(MFMat_White)); } MFRenderer_Begin(); }
void HKWidgetRenderer::Render(const HKWidget &widget, const MFMatrix &worldTransform) { MFVector widgetColour = widget.GetColour(); MFVector size = widget.GetSize(); size.x -= padding.x + padding.z; size.y -= padding.y + padding.w; if(colour.w > 0.f) { float borderWidth = border.x + border.z; float borderHeight = border.y + border.w; MFPrimitive_DrawUntexturedQuad(padding.x + border.x, padding.y + border.y, size.x - borderWidth, size.y - borderHeight, colour*widgetColour, worldTransform); } if(border.x > 0.f) // left MFPrimitive_DrawUntexturedQuad(padding.x, padding.y, border.x, size.y, borderColour*widgetColour, worldTransform); if(border.y > 0.f) // top MFPrimitive_DrawUntexturedQuad(padding.x, padding.y, size.x, border.y, borderColour*widgetColour, worldTransform); if(border.z > 0.f) // right MFPrimitive_DrawUntexturedQuad(size.x - border.z + padding.x, padding.y, border.z, size.y, borderColour*widgetColour, worldTransform); if(border.w > 0.f) // bottom MFPrimitive_DrawUntexturedQuad(padding.x, padding.y + size.y - border.w, size.x, border.w, borderColour*widgetColour, worldTransform); if(pImage) { if(margin9Cell > 0.f) { // 9 cell stuff... } else { // draw the background image centered in the box MFMaterial_SetMaterial(pImage); float offset = 0; float tc = MFRenderer_GetTexelCenterOffset(); if(tc > 0.f) { if(size.x == texWidth && size.y == texHeight) offset = tc; } MFPrimitive_DrawQuad(padding.x - offset, padding.y - offset, size.x, size.y, widgetColour, 0, 0, 1, 1, worldTransform); } } }
MF_API void MFDebug_DebugAssert(const char *pReason, const char *pMessage, const char *pFile, int line) { MFDebug_Message(MFStr("%s(%d) : Assertion Failure.",pFile,line)); MFDebug_Message(MFStr("Failed Condition: %s\n%s", pReason, pMessage)); #if !defined(_RETAIL) MFCallstack_Log(); #endif #if defined(MF_LINUX) || defined(MF_OSX) MFDebug_Breakpoint(); #endif if(!MFFont_GetDebugFont()) return; while(!gQuit) { MFSystem_HandleEventsPlatformSpecific(); MFSystem_UpdateTimeDelta(); gFrameCount++; MFSystem_Update(); MFSystem_PostUpdate(); MFRenderer_BeginFramePlatformSpecific(); MFRenderer_SetClearColour(0,0,0,0); MFRenderer_ClearScreen(); MFView_SetDefault(); MFView_SetOrtho(); if(!(((uint32)gSystemTimer.GetSecondsF()) % 2)) { MFMaterial_SetMaterial(MFMaterial_GetStockMaterial(MFMat_White)); MFPrimitive(PT_QuadList); MFBegin(4); MFSetColour(1,0,0,1); MFSetPosition(50, 50, 0); MFSetPosition(590, 110, 0); MFSetColour(0,0,0,1); MFSetPosition(55, 55, 0); MFSetPosition(585, 105, 0); MFEnd(); } MFFont_DrawText2f(MFFont_GetDebugFont(), 110, 60, 20, MakeVector(1,0,0,1), "Software Failure. Press left mouse button to continue."); MFFont_DrawText2f(MFFont_GetDebugFont(), 240, 80, 20, MakeVector(1,0,0,1), "Guru Meditation: "); MFFont_DrawText2f(MFFont_GetDebugFont(), 80, 120, 20, MakeVector(1,0,0,1), "Assertion Failure:"); MFFont_DrawText2f(MFFont_GetDebugFont(), 80, 140, 20, MakeVector(1,0,0,1), MFStr("Failed Condition: %s", pReason)); MFFont_DrawText2f(MFFont_GetDebugFont(), 80, 160, 20, MakeVector(1,0,0,1), MFStr("File: %s, Line: %d", pFile, line)); MFFont_DrawText2f(MFFont_GetDebugFont(), 80, 190, 20, MakeVector(1,0,0,1), MFStr("Message: %s", pMessage)); #if !defined(_RETAIL) MFFont_DrawText2f(MFFont_GetDebugFont(), 80, 230, 20, MakeVector(1,0,0,1), "Callstack:"); MFFont_DrawText2f(MFFont_GetDebugFont(), 100, 250.0f, 20, MakeVector(1,0,0,1), MFCallstack_GetCallstackString()); #else MFFont_DrawText2f(MFFont_GetDebugFont(), 80, 230, 20, MakeVector(1,0,0,1), "Callstack not available in RETAIL builds"); #endif // MFSystem_Draw(); MFRenderer_EndFramePlatformSpecific(); } }
void MFCollision_DrawItem(MFCollisionItem *pItem) { // maybe reject it if its not in range.. MFVector colour = (pItem->flags & MFCIF_Disabled) ? MakeVector(1,0,0,1) : ((pItem->flags & MFCIF_Dynamic) ? MakeVector(0,0,1,1) : MakeVector(0,1,0,1)); MFMaterial_SetMaterial(MFMaterial_GetStockMaterial(MFMat_White)); switch(pItem->pTemplate->type) { case MFCT_Sphere: { MFCollisionSphere *pSphere = (MFCollisionSphere*)pItem->pTemplate->pCollisionTemplateData; MFPrimitive_DrawSphere(MFVector::zero, pSphere->radius, 8, 7, colour, pItem->worldPos, true); break; } case MFCT_Mesh: { MFCollisionMesh *pMesh = (MFCollisionMesh*)pItem->pTemplate->pCollisionTemplateData; int a; // draw each triangle MFPrimitive(PT_TriList); MFSetMatrix(pItem->worldPos); MFBegin(pMesh->numTris * 3); MFSetColour(1.0f, 1.0f, 1.0f, 0.5f); for(a=0; a<pMesh->numTris; a++) { if(pMesh->pTriangles[a].flags) MFSetColour(1.0f, 0.0f, 0.0f, 0.5f); MFSetPositionV(pMesh->pTriangles[a].verts[0]); MFSetPositionV(pMesh->pTriangles[a].verts[1]); MFSetPositionV(pMesh->pTriangles[a].verts[2]); if(pMesh->pTriangles[a].flags) { MFSetColour(1.0f, 1.0f, 1.0f, 0.5f); pMesh->pTriangles[a].flags = 0; } } MFEnd(); // draw each triangle outline MFPrimitive(PT_LineList); MFSetMatrix(pItem->worldPos); MFBegin(pMesh->numTris * 12); MFSetColourV(colour); for(a=0; a<pMesh->numTris; a++) { MFSetPositionV(pMesh->pTriangles[a].verts[0]); MFSetPositionV(pMesh->pTriangles[a].verts[1]); MFSetPositionV(pMesh->pTriangles[a].verts[1]); MFSetPositionV(pMesh->pTriangles[a].verts[2]); MFSetPositionV(pMesh->pTriangles[a].verts[2]); MFSetPositionV(pMesh->pTriangles[a].verts[0]); MFVector e1, e2, e3; e1 = (pMesh->pTriangles[a].verts[0] + pMesh->pTriangles[a].verts[1]) * 0.5f; e2 = (pMesh->pTriangles[a].verts[1] + pMesh->pTriangles[a].verts[2]) * 0.5f; e3 = (pMesh->pTriangles[a].verts[2] + pMesh->pTriangles[a].verts[0]) * 0.5f; MFSetPositionV(e1); MFSetPositionV(e1 + pMesh->pTriangles[a].edgePlanes[0] * 2.0f); MFSetPositionV(e2); MFSetPositionV(e2 + pMesh->pTriangles[a].edgePlanes[1] * 2.0f); MFSetPositionV(e3); MFSetPositionV(e3 + pMesh->pTriangles[a].edgePlanes[2] * 2.0f); // MFVector c = (pMesh->pTriangles[a].verts[0] + pMesh->pTriangles[a].verts[1] + pMesh->pTriangles[a].verts[2]) * (1.0f / 3.0f); // MFSetPosition(c); // MFSetPosition(c + pMesh->pTriangles[a].plane*3.0f); } MFEnd(); break; } case MFCT_Field: break; default: break; } }
void Game_Draw() { MFCALLSTACK; MFRenderer_SetClearColour(0.f, 0.f, 0.2f, 1.f); MFRenderer_ClearScreen(); // Set identity camera (no camera) MFView_Push(); MFView_SetAspectRatio(MFDisplay_GetNativeAspectRatio()); MFView_SetProjection(); MFMaterial_SetMaterial(MFMaterial_GetStockMaterial(MFMat_White)); // set the world matrix to identity MFMatrix world = MFMatrix::identity; // move the box into the scene (along the z axis) world.Translate(MakeVector(0, 0, 5)); // increment rotation static float rotation = 0.0f; rotation += MFSystem_TimeDelta(); // rotate the box world.RotateYPR(rotation, rotation * 2.0f, rotation * 0.5f); // begin rendering the box MFPrimitive(PT_TriList); MFSetMatrix(world); // begin rendering 12 triangles (12 * 3 vertices) MFBegin(3 * 12); // draw a bunch of triangles MFSetColour(1,0,0,1); MFSetPosition(-1,-1, -1); MFSetPosition(-1, 1, -1); MFSetPosition( 1, 1, -1); MFSetPosition(-1,-1, -1); MFSetPosition( 1, 1, -1); MFSetPosition( 1,-1, -1); MFSetColour(0,1,0,1); MFSetPosition(-1,-1,1); MFSetPosition( 1,-1,1); MFSetPosition( 1, 1,1); MFSetPosition(-1,-1,1); MFSetPosition( 1, 1,1); MFSetPosition(-1, 1,1); MFSetColour(0,0,1,1); MFSetPosition( 1,-1,1); MFSetPosition( 1,-1,-1); MFSetPosition( 1, 1,-1); MFSetPosition( 1,-1,1); MFSetPosition( 1, 1,-1); MFSetPosition( 1, 1,1); MFSetColour(1,0,1,1); MFSetPosition(-1,-1,1); MFSetPosition(-1, 1,1); MFSetPosition(-1, 1,-1); MFSetPosition(-1,-1,1); MFSetPosition(-1, 1,-1); MFSetPosition(-1,-1,-1); MFSetColour(1,1,0,1); MFSetPosition(-1, 1,1); MFSetPosition( 1, 1,1); MFSetPosition( 1, 1,-1); MFSetPosition(-1, 1,1); MFSetPosition( 1, 1,-1); MFSetPosition(-1, 1,-1); MFSetColour(0,1,1,1); MFSetPosition(-1,-1,1); MFSetPosition(-1,-1,-1); MFSetPosition( 1,-1,-1); MFSetPosition(-1,-1,1); MFSetPosition( 1,-1,-1); MFSetPosition( 1,-1,1); MFEnd(); MFRect disp; MFDisplay_GetDisplayRect(&disp); MFView_SetOrtho(&disp); pUI->Draw(); MFView_Pop(); }
void Menu::Draw() { MFVector dimensions = MakeVector(0.0f, 0.0f, 0.0f); MFVector currentPos; float requestedWidth = menuDimensions.x-40.0f; float selStart, selEnd; int a; // get menu size for(a=0; a<numChildren; a++) { MFVector dim = pChildren[a]->GetDimensions(requestedWidth); if(selection==a) { selStart = dimensions.y; selEnd = selStart + dim.y; if(selStart < -yOffset) { targetOffset = -selStart; } if(selEnd > menuDimensions.y - 75.0f - yOffset) { targetOffset = -(selEnd-(menuDimensions.y-75.0f)); } } dimensions.y += dim.y; dimensions.x = MFMax(dimensions.x, dim.x); } if(targetOffset != yOffset) { yOffset -= MFAbs(yOffset-targetOffset) < 0.1f ? yOffset-targetOffset : (yOffset-targetOffset)*0.1f; } currentPos = MakeVector(menuPosition.x+20.0f, menuPosition.y+50.0f + yOffset, 0.0f); MFPrimitive(PT_TriStrip|PT_Untextured); MFBegin(4); MFSetColourV(colour*0.4f); MFSetPosition(menuPosition.x, menuPosition.y, 0); MFSetColourV(colour*0.8f); MFSetPosition(menuPosition.x+menuDimensions.x, menuPosition.y, 0); MFSetColourV(colour*0.6f); MFSetPosition(menuPosition.x, menuPosition.y+menuDimensions.y, 0); MFSetColourV(colour); MFSetPosition(menuPosition.x+menuDimensions.x, menuPosition.y+menuDimensions.y, 0); MFEnd(); MFFont_DrawText2(MFFont_GetDebugFont(), menuPosition.x+10.0f, menuPosition.y+5.0f, MENU_FONT_HEIGHT*1.5f, MakeVector(1,0.6875f,0.5f,1), name); MFMaterial_SetMaterial(MFMaterial_GetStockMaterial(MFMat_SysLogoSmall)); float logoMargin = 5.0f; float iconSize = 35.0f; MFPrimitive(PT_TriStrip); MFBegin(4); MFSetColourV(MFVector::white); MFSetTexCoord1(0,0); MFSetPosition((menuPosition.x+menuDimensions.x) - logoMargin*2 - iconSize, menuPosition.y + logoMargin, 0); MFSetTexCoord1(1,0); MFSetPosition((menuPosition.x+menuDimensions.x) - logoMargin*2, menuPosition.y + logoMargin, 0); MFSetTexCoord1(0,1); MFSetPosition((menuPosition.x+menuDimensions.x) - logoMargin*2 - iconSize, menuPosition.y + logoMargin + iconSize, 0); MFSetTexCoord1(1,1); MFSetPosition((menuPosition.x+menuDimensions.x) - logoMargin*2, menuPosition.y + logoMargin + iconSize, 0); MFEnd(); #if MF_RENDERER == MF_DRIVER_D3D9 || MF_RENDERER == MF_DRIVER_XBOX pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); #endif MFPrimitive(PT_TriStrip|PT_Untextured); MFBegin(4); MFSetColour(0.f, 0.f, 0.f, 0.65f); MFSetPosition(menuPosition.x+15, menuPosition.y+45, 0); MFSetPosition(menuPosition.x+menuDimensions.x-15, menuPosition.y+45, 0); MFSetPosition(menuPosition.x+15, menuPosition.y+menuDimensions.y-15, 0); MFSetPosition(menuPosition.x+menuDimensions.x-15, menuPosition.y+menuDimensions.y-15, 0); MFEnd(); #if MF_RENDERER == MF_DRIVER_D3D9 || MF_RENDERER == MF_DRIVER_XBOX pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESS); pd3dDevice->SetRenderState(D3DRS_STENCILREF, 0); #endif for(a=0; a<numChildren; a++) { if(currentPos.y > menuPosition.y + menuDimensions.y - 15.0f) break; if(selection==a) { float height = pChildren[a]->GetDimensions(requestedWidth).y; if(currentPos.y + height < menuPosition.y + 45.0f) { currentPos.y += height; continue; } MFPrimitive(PT_TriStrip|PT_Untextured); MFBegin(4); MFSetColour(0.f, 0.f, .5f, .75f); MFSetPosition(menuPosition.x+15, currentPos.y, 0); MFSetColour(0.f, 0.f, .8f, .75f); MFSetPosition(menuPosition.x+menuDimensions.x-15, currentPos.y, 0); MFSetColour(0.f, 0.f, .56f, .75f); MFSetPosition(menuPosition.x+15, currentPos.y + height, 0); MFSetColour(0.f, 0.f, .1f, .75f); MFSetPosition(menuPosition.x+menuDimensions.x-15, currentPos.y + height, 0); MFEnd(); } currentPos.y += pChildren[a]->ListDraw(selection==a, currentPos, requestedWidth); } #if MF_RENDERER == MF_DRIVER_D3D9 || MF_RENDERER == MF_DRIVER_XBOX pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); #endif }
void dBFrame::Draw() { if(!pMat) { MFPrimitive_DrawUntexturedQuad(rect.x-10, rect.y-10, rect.width+20, rect.height+20, colours[0]); } else { // draw background float x, y, xRemaining, yRemaining; // calculate number of tiles (including edges) int h = (int)MFCeil(rect.width / borderWidth); int w = (int)MFCeil(rect.height / borderWidth); int numTiles = (h + 2) * (w + 2); // begin immediate renderer MFMaterial_SetMaterial(pMat); MFPrimitive(PT_QuadList); MFBegin(numTiles*2); MFSetColourV(colours[0]); // render tiled background yRemaining = rect.height; for(y = 0.0f; y < rect.height; y += borderWidth) { xRemaining = rect.width; for(x = 0.0f; x < rect.width; x += borderWidth) { float xuv = xRemaining < borderWidth ? 0.25f * (xRemaining / borderWidth) : 0.25f; float yuv = yRemaining < borderWidth ? 0.25f * (yRemaining / borderWidth) : 0.25f; MFSetTexCoord1(0.25f, 0.25f); MFSetPosition(rect.x + x, rect.y + y, 0); MFSetTexCoord1(0.25f + xuv, 0.25f + yuv); MFSetPosition(rect.x + x + MFMin(borderWidth, xRemaining), rect.y + y + MFMin(borderWidth, yRemaining), 0); xRemaining -= borderWidth; } yRemaining -= borderWidth; } // draw frame // draw corners MFSetTexCoord1(0.0f, 0.0f); MFSetPosition(rect.x - borderWidth, rect.y - borderWidth, 0.0f); MFSetTexCoord1(0.25f, 0.25f); MFSetPosition(rect.x, rect.y, 0.0f); MFSetTexCoord1(0.5f, 0.0f); MFSetPosition(rect.x + rect.width, rect.y - borderWidth, 0.0f); MFSetTexCoord1(0.75f, 0.25f); MFSetPosition(rect.x + rect.width + borderWidth, rect.y, 0.0f); MFSetTexCoord1(0.0f, 0.50f); MFSetPosition(rect.x - borderWidth, rect.y + rect.height, 0.0f); MFSetTexCoord1(0.25f, 0.75f); MFSetPosition(rect.x, rect.y + rect.height + borderWidth, 0.0f); MFSetTexCoord1(0.5f, 0.5f); MFSetPosition(rect.x + rect.width, rect.y + rect.height, 0.0f); MFSetTexCoord1(0.75f, 0.75f); MFSetPosition(rect.x + rect.width + borderWidth, rect.y + rect.height + borderWidth, 0.0f); // draw vertical edges yRemaining = rect.height; for(y = 0.0f; y < rect.height; y += borderWidth) { float yuv = yRemaining < borderWidth ? 0.25f * (yRemaining / borderWidth) : 0.25f; MFSetTexCoord1(0.0f, 0.25f); MFSetPosition(rect.x - borderWidth, rect.y + y, 0.0f); MFSetTexCoord1(0.25f, 0.25f + yuv); MFSetPosition(rect.x, rect.y + y + MFMin(borderWidth, yRemaining), 0.0f); MFSetTexCoord1(0.5f, 0.25f); MFSetPosition(rect.x + rect.width, rect.y + y, 0.0f); MFSetTexCoord1(0.75f, 0.25f + yuv); MFSetPosition(rect.x + rect.width + borderWidth, rect.y + y + MFMin(borderWidth, yRemaining), 0.0f); yRemaining -= borderWidth; } // draw horizontal edges xRemaining = rect.width; for(x = 0.0f; x < rect.width; x += borderWidth) { float xuv = xRemaining < borderWidth ? 0.25f * (xRemaining / borderWidth) : 0.25f; MFSetTexCoord1(0.25f, 0.0f); MFSetPosition(rect.x + x, rect.y - borderWidth, 0.0f); MFSetTexCoord1(0.25f + xuv, 0.25f); MFSetPosition(rect.x + x + MFMin(borderWidth, xRemaining), rect.y, 0.0f); MFSetTexCoord1(0.25f, 0.5f); MFSetPosition(rect.x + x, rect.y + rect.height, 0.0f); MFSetTexCoord1(0.25f + xuv, 0.75f); MFSetPosition(rect.x + x + MFMin(borderWidth, xRemaining), rect.y + rect.height + borderWidth, 0.0f); xRemaining -= borderWidth; } MFEnd(); } }
MF_API void MFParticleSystem_Draw(MFParticleSystem *pParticleSystem) { int numParticles = pParticleSystem->particles.GetLength(); if(numParticles == 0) return; // render particles MFView_Push(); MFMatrix ltv = MFView_GetWorldToViewMatrix(); MFView_SetCameraMatrix(MFMatrix::identity); // update and draw each particle if(pParticleSystem->params.rotationRate != 0.0f) { MFParticleSystem_DrawRotating(pParticleSystem, ltv); MFView_Pop(); return; } float fadeStart = pParticleSystem->params.life - pParticleSystem->params.fadeDelay; MFMaterial_SetMaterial(pParticleSystem->pMaterial); MFPrimitive(PT_QuadList, 0); MFBegin(numParticles * 2); MFParticle **ppI = pParticleSystem->particles.Begin(); while(*ppI) { MFParticle *pParticle = *ppI; float dt = MFSystem_TimeDelta(); pParticle->size += pParticleSystem->params.scaleRate * dt; pParticle->velocity += pParticleSystem->params.force * dt; pParticle->pos += pParticle->velocity * dt; float halfSize = pParticle->size * 0.5f; float alpha = MFMin(pParticle->life / fadeStart, 1.0f); MFVector pos = ApplyMatrixH(pParticle->pos, ltv); MFSetColourV(MakeVector(pParticle->colour, pParticle->colour.w * alpha)); MFSetTexCoord1(0, 0); MFSetPosition(pos.x - halfSize, pos.y + halfSize, pos.z); MFSetTexCoord1(1, 1); MFSetPosition(pos.x + halfSize, pos.y - halfSize, pos.z); pParticle->life -= dt; if(pParticle->life < 0.0f) pParticleSystem->particles.Destroy(ppI); ppI++; } MFEnd(); MFView_Pop(); }
void Fretboard::Draw(float time, dBChart *pSong, int track) { MFCALLSTACKc; MFView_Push(); MFRect rect; MFView_GetViewport(&rect); float aspect = rect.width / rect.height; aspect = MFClamp(0.82f, aspect, 2.0f); MFView_SetAspectRatio(aspect); if(viewPoint == 0) { // incoming MFView_ConfigureProjection(MFDEGREES(65.0f)/aspect, 1.0f, 100.0f); // Setup the Camera in 3D space. MFMatrix cameraMatrix; MFVector start = MakeVector( 0, 8, 3 ); MFVector dir = MakeVector( 0, 5, -8 ); dir = (dir-start) * (1.0f/1.777777777f); cameraMatrix.LookAt(start + dir*aspect, MakeVector(0.0f, 0.0f, 5.0f)); MFView_SetCameraMatrix(cameraMatrix); } else if(viewPoint == 1) { // overhead MFView_ConfigureProjection(MFDEGREES(45.0f), 1.0f, 100.0f); /* float aspect = MFDisplay_GetNativeAspectRatio(); MFView_SetAspectRatio(aspect); MFRect projRect; projRect.y = 15; projRect.height = -30; projRect.x = -projRect.y * aspect; projRect.width = -projRect.height * aspect; MFView_SetOrtho(&projRect); */ // Setup the Camera in 3D space. MFMatrix cameraMatrix; cameraMatrix.LookAt(MakeVector(0, 30, 10), MakeVector(0, 0, 10), MakeVector(0, 0, 1)); MFView_SetCameraMatrix(cameraMatrix); } else if(viewPoint == 2) { // overhead MFView_ConfigureProjection(MFDEGREES(45.0f), 1.0f, 100.0f); /* float aspect = MFDisplay_GetNativeAspectRatio(); MFView_SetAspectRatio(aspect); MFRect projRect; projRect.y = 15; projRect.height = -30; projRect.x = -projRect.y * aspect; projRect.width = -projRect.height * aspect; MFView_SetOrtho(&projRect); */ // Setup the Camera in 3D space. MFMatrix cameraMatrix; cameraMatrix.LookAt(MakeVector(0, 20, 13), MakeVector(0, 0, 13), MakeVector(-1, 0, 0)); MFView_SetCameraMatrix(cameraMatrix); } MFView_SetProjection(); MFMaterial *pFB = pSong->pFretboard ? pSong->pFretboard : pFretboard; MFMaterial_SetMaterial(pFB); MFPrimitive(PT_TriStrip, 0); int start = -4; int end = 60; int fadeStart = end - 10; float fretboardRepeat = 15.0f; float fretboardWidth = 7.0f; float columnWidth = fretboardWidth / 5.0f; float ringBorder = 0.1f; // draw the fretboard... MFBegin(((end-start) / 4) * 2 + 2); MFSetColourV(MFVector::white); float halfFB = fretboardWidth*0.5f; float offset = time*scrollSpeed; float topTime = time + end/scrollSpeed; float bottomTime = time + start/scrollSpeed; int a; float textureOffset = fmodf(offset, fretboardRepeat); for(a=start; a<end; a+=4) { float z = (float)a; MFSetTexCoord1(1.0f, 1.0f - (z+textureOffset) / fretboardRepeat); MFSetPosition(halfFB, 0.0f, z); MFSetTexCoord1(0.0f, 1.0f - (z+textureOffset) / fretboardRepeat); MFSetPosition(-halfFB, 0.0f, z); } float z = (float)a; MFSetTexCoord1(1.0f, 1.0f - (z+textureOffset) / fretboardRepeat); MFSetPosition(halfFB, 0.0f, z); MFSetTexCoord1(0.0f, 1.0f - (z+textureOffset) / fretboardRepeat); MFSetPosition(-halfFB, 0.0f, z); MFEnd(); // draw the selection region MFMaterial_SetMaterial(pFrets); MFPrimitive(PT_TriStrip, 0); if(gEditor.selectStart != gEditor.selectEnd) { float selectStartTime = GETSECONDS(pSong->CalculateTimeOfTick(gEditor.selectStart)); float selectEndTime = GETSECONDS(pSong->CalculateTimeOfTick(gEditor.selectEnd)); if(selectStartTime < topTime && selectEndTime > bottomTime) { selectStartTime = (MFMax(bottomTime, selectStartTime) - time) * scrollSpeed; selectEndTime = (MFMin(topTime, selectEndTime) - time) * scrollSpeed; MFBegin(4); MFSetColour(1.0f, 0.0f, 0.0f, 0.5f); MFSetPosition(-halfFB, 0.0f, selectEndTime); MFSetPosition(halfFB, 0.0f, selectEndTime); MFSetPosition(-halfFB, 0.0f, selectStartTime); MFSetPosition(halfFB, 0.0f, selectStartTime); MFEnd(); } } // draw the fretboard edges and bar lines const float barWidth = 0.2f; MFMaterial_SetMaterial(pBar); MFPrimitive(PT_TriStrip, 0); MFBegin(4); MFSetColour(0.0f, 0.0f, 0.0f, 0.8f); MFSetTexCoord1(0,0); MFSetPosition(-halfFB, 0.0f, barWidth); MFSetTexCoord1(1,0); MFSetPosition(halfFB, 0.0f, barWidth); MFSetTexCoord1(0,1); MFSetPosition(-halfFB, 0.0f, -barWidth); MFSetTexCoord1(1,1); MFSetPosition(halfFB, 0.0f, -barWidth); MFEnd(); MFMaterial_SetMaterial(pEdge); MFPrimitive(PT_TriStrip, 0); MFBegin(34); MFSetColour(0.0f, 0.0f, 0.0f, 0.3f); for(int col=1; col<5; col++) { if(col > 1) MFSetPosition(-halfFB + columnWidth*(float)col - 0.02f, 0.0f, (float)end); MFSetTexCoord1(0,0); MFSetPosition(-halfFB + columnWidth*(float)col - 0.02f, 0.0f, (float)end); MFSetTexCoord1(1,0); MFSetPosition(-halfFB + columnWidth*(float)col + 0.02f, 0.0f, (float)end); MFSetTexCoord1(0,1); MFSetPosition(-halfFB + columnWidth*(float)col - 0.02f, 0.0f, (float)start); MFSetTexCoord1(1,1); MFSetPosition(-halfFB + columnWidth*(float)col + 0.02f, 0.0f, (float)start); MFSetPosition(-halfFB + columnWidth*(float)col + 0.02f, 0.0f, (float)start); } MFSetColourV(MFVector::white); MFSetPosition(-halfFB - 0.1f, 0.0f, (float)end); MFSetTexCoord1(0,0); MFSetPosition(-halfFB - 0.1f, 0.0f, (float)end); MFSetTexCoord1(1,0); MFSetPosition(-halfFB + 0.1f, 0.0f, (float)end); MFSetTexCoord1(0,1); MFSetPosition(-halfFB - 0.1f, 0.0f, (float)start); MFSetTexCoord1(1,1); MFSetPosition(-halfFB + 0.1f, 0.0f, (float)start); MFSetPosition(-halfFB + 0.1f, 0.0f, (float)start); MFSetPosition(halfFB - 0.1f, 0.0f, (float)end); MFSetTexCoord1(0,0); MFSetPosition(halfFB - 0.1f, 0.0f, (float)end); MFSetTexCoord1(1,0); MFSetPosition(halfFB + 0.1f, 0.0f, (float)end); MFSetTexCoord1(0,1); MFSetPosition(halfFB - 0.1f, 0.0f, (float)start); MFSetTexCoord1(1,1); MFSetPosition(halfFB + 0.1f, 0.0f, (float)start); MFEnd(); // draw the frets.... MFMaterial_SetMaterial(pBar); MFPrimitive(PT_TriStrip, 0); int bottomTick = pSong->CalculateTickAtTime((int64)(bottomTime*1000000.0f)); int res = pSong->GetRes(); int ticks = bHalfFrets ? res/2 : res; int fretBeat = bottomTick + ticks - 1; fretBeat -= fretBeat % ticks; float fretTime = GETSECONDS(pSong->CalculateTimeOfTick(fretBeat)); while(fretTime < topTime) { bool halfBeat = (fretBeat % res) != 0; bool bar = false; if(!halfBeat) { GHEvent *pLastTS = pSong->sync.GetMostRecentEvent(GHE_TimeSignature, fretBeat); if(pLastTS) bar = ((fretBeat - pLastTS->tick) % (pLastTS->parameter*res)) == 0; else if(fretBeat == 0) bar = true; } float bw = bar ? barWidth : barWidth*0.5f; MFBegin(4); float position = (fretTime - time) * scrollSpeed; if(!halfBeat) MFSetColourV(MFVector::white); else MFSetColourV(MakeVector(1,1,1,0.3f)); MFSetTexCoord1(0,0); MFSetPosition(-halfFB, 0.0f, position + bw); MFSetTexCoord1(1,0); MFSetPosition(halfFB, 0.0f, position + bw); MFSetTexCoord1(0,1); MFSetPosition(-halfFB, 0.0f, position + -bw); MFSetTexCoord1(1,1); MFSetPosition(halfFB, 0.0f, position + -bw); MFEnd(); fretBeat += ticks; fretTime = GETSECONDS(pSong->CalculateTimeOfTick(fretBeat)); } // draw the notes... GHEventManager ¬eStream = pSong->notes[track]; GHEvent *pEv = noteStream.First(); int64 topTimeus = (int64)(topTime*1000000.0f); while(pEv && pEv->time < topTimeus) { if((pEv->event == GHE_Note || pEv->event == GHE_Special) && pEv->tick + pEv->parameter >= bottomTick) { float evTime = GETSECONDS(pEv->time); // TODO: we need to calculate the end of the hold... float noteEnd = evTime; if(pEv->parameter) noteEnd = GETSECONDS(pSong->CalculateTimeOfTick(pEv->tick + pEv->parameter)); if(pEv->event == GHE_Note && pEv->played != 1) { // draw a note int key = pEv->key; bool tap = false; // check if there is a previous note, and it is in range if(pEv->Prev() && pEv->Prev()->tick < pEv->tick && pEv->Prev()->tick > pEv->tick - (res/2) && pEv->Prev()->key != pEv->key && (!pEv->Next() || !(pEv->Next()->tick == pEv->tick)) && !pEv->Prev()->parameter && !(pEv->Prev()->Prev() && pEv->Prev()->Prev()->tick == pEv->Prev()->tick)) { tap = true; } int noteX = gConfig.controls.leftyFlip[0] ? 4-key : key; float position = (GETSECONDS(pEv->time) - time)*scrollSpeed; float xoffset = -halfFB + columnWidth*0.5f + (float)noteX*columnWidth; if(pEv->parameter) { MFMaterial_SetMaterial(pFrets); float whammyTop = (noteEnd - time)*scrollSpeed; MFPrimitive(PT_TriStrip, 0); // TODO: we could consider not drawing this part of the hold line.. seems reasonable that it terminates at the line... if(gEditor.state == GHPS_Stopped) { if(position < 0.0f) { MFBegin(4); MFSetColourV(gColours[key]); MFSetPosition(xoffset - 0.2f, 0.0f, MFMin(whammyTop, 0.0f)); MFSetPosition(xoffset + 0.2f, 0.0f, MFMin(whammyTop, 0.0f)); MFSetPosition(xoffset - 0.2f, 0.0f, position); MFSetPosition(xoffset + 0.2f, 0.0f, position); MFEnd(); } } if(whammyTop > 0.0f) { // this half could have waves cruising down it if we wanted to support the whammy... MFBegin(4); MFSetColourV(gColours[key]); MFSetPosition(xoffset - 0.2f, 0.0f, MFMin(whammyTop, (float)end)); MFSetPosition(xoffset + 0.2f, 0.0f, MFMin(whammyTop, (float)end)); MFSetPosition(xoffset - 0.2f, 0.0f, MFMax(position, 0.0f)); MFSetPosition(xoffset + 0.2f, 0.0f, MFMax(position, 0.0f)); MFEnd(); } } if(evTime >= bottomTime) { MFMatrix mat; mat.SetScale(MakeVector(0.5f/20, 0.5f/20, 0.5f/20)); mat.Translate(MakeVector(xoffset, 0.03f, position)); MFModel_SetWorldMatrix(pButton, mat); MFStateBlock *pSB = MFStateBlock_CreateTemporary(64); MFStateBlock_SetVector(pSB, MFSCV_DiffuseColour, pEv->played == -1 ? MakeVector(0.3f, 0.3f, 0.3f, 1.0f) : MFVector::white); // MFStateBlock_SetVector(pSB, MFSCV_DiffuseColour, position < 0.0f ? MakeVector(0.3f, 0.3f, 0.3f, 1.0f) : MFVector::white); // MFRenderer_SetRenderStateOverride(MFRS_MaterialOverride, (uint32&)(tap ? pButtonMat[key] : pButtonRing[key])); MFRenderer_AddModel(pButton, pSB, MFView_GetViewState()); // render the note time if(bRenderNoteTimes) { MFView_Push(); MFView_SetOrtho(&rect); MFVector pos; MFView_TransformPoint3DTo2D(MakeVector(xoffset, 0.0f, position), &pos); pos.x += 16.0f; pos.y -= 26.0f; int minutes = (int)(pEv->time / 60000000); int seconds = (int)((pEv->time % 60000000) / 1000000); int milliseconds = (int)((pEv->time % 1000000) / 1000); MFFont_DrawTextf(pText, pos, 20.0f, MFVector::yellow, "%s: %d:%02d.%d\nTick: %g", MFTranslation_GetString(pStrings, TRACK_TIME), minutes, seconds, milliseconds, (float)pEv->tick/res); MFView_Pop(); } } } if(pEv->event == GHE_Special) { // static MFVector specialColours[3] = { MakeVector(1,0,0,1), MakeVector(1,1,0,1), MakeVector(0,0,1,1) }; // static float specialX[3] = { halfFB + 0.2f, halfFB + 1, -halfFB - 1 }; // static float specialWidth[3] = { 0.8f, 0.8f, 0.8f }; static MFVector specialColours[3] = { MakeVector(1,0,0,0.5f), MakeVector(1,1,0,0.5f), MakeVector(0,0,1,0.5f) }; static float specialX[3] = { -halfFB, halfFB - 0.8f, -halfFB }; static float specialWidth[3] = { 0.8f, 0.8f, fretboardWidth }; float bottom = (evTime - time)*scrollSpeed; float top = (noteEnd - time)*scrollSpeed; int key = pEv->key; MFMaterial_SetMaterial(pFrets); MFPrimitive(PT_TriStrip, 0); MFBegin(4); MFSetColourV(specialColours[key]); MFSetPosition(specialX[key], 0.0f, MFMin(top, (float)end)); MFSetPosition(specialX[key]+specialWidth[key], 0.0f, MFMin(top, (float)end)); MFSetPosition(specialX[key], 0.0f, MFMax(bottom, (float)start)); MFSetPosition(specialX[key]+specialWidth[key], 0.0f, MFMax(bottom, (float)start)); MFEnd(); } } pEv = pEv->Next(); } // MFRenderer_SetRenderStateOverride(MFRS_MaterialOverride, NULL); // draw circles at the bottom.. MFMaterial_SetMaterial(pRing); for(int a=0; a<5; a++) { DrawRing(-halfFB + (float)a*columnWidth + columnWidth*ringBorder, 0.0f, columnWidth*(1.0f-ringBorder*2)); } for(int a=0; a<5; a++) { dBControlType keys_righty[] = { dBCtrl_Edit_Note0, dBCtrl_Edit_Note1, dBCtrl_Edit_Note2, dBCtrl_Edit_Note3, dBCtrl_Edit_Note4 }; dBControlType keys_lefty[] = { dBCtrl_Edit_Note4, dBCtrl_Edit_Note3, dBCtrl_Edit_Note2, dBCtrl_Edit_Note1, dBCtrl_Edit_Note0 }; dBControlType *keys = gConfig.controls.leftyFlip[0] ? keys_lefty : keys_righty; int ringPos = gConfig.controls.leftyFlip[0] ? 4-a : a; MFMaterial_SetMaterial(pColourRing[a]); DrawRing(-halfFB + (float)ringPos*columnWidth, 0.0f, columnWidth, !TestControl(keys[a], GHCT_Hold)); } // render trigger particles MFParticleSystem_Draw(pParticles); // render text and stuff MFView_SetOrtho(&rect); pEv = pSong->sync.GetNextEvent(bottomTick); while(pEv && pEv->time < topTimeus) { float evTime = GETSECONDS(pEv->time); if(evTime > bottomTime) { if(pEv->event == GHE_BPM) { float position = (evTime - time) * scrollSpeed; MFVector pos; MFView_TransformPoint3DTo2D(MakeVector(halfFB + 0.2f, 0.0f, position), &pos); pos.y -= 12.0f; MFFont_DrawTextf(pText, pos, 24.0f, MakeVector(0,0.5f,0,1), "%s: %g", MFTranslation_GetString(pStrings, TRACK_BPM), (float)pEv->parameter * 0.001f); } if(pEv->event == GHE_Anchor) { int minutes = (int)(pEv->time / 60000000); int seconds = (int)((pEv->time%60000000)/1000000); int milliseconds = (int)((pEv->time%1000000)/1000); float position = (evTime - time) * scrollSpeed; MFVector pos; MFView_TransformPoint3DTo2D(MakeVector(halfFB + 0.2f, 0.0f, position), &pos); pos.y -= 12.0f; MFFont_DrawTextf(pText, pos, 24.0f, MakeVector(0,0.5f,0,1), "A: %02d:%02d.%03d\n %s: %g", minutes, seconds, milliseconds, MFTranslation_GetString(pStrings, TRACK_BPM), (float)pEv->parameter * 0.001f); } else if(pEv->event == GHE_TimeSignature) { float position = (evTime - time) * scrollSpeed; MFVector pos; MFView_TransformPoint3DTo2D(MakeVector(-halfFB - 0.2f, 0.0f, position), &pos); const char *pString = MFStr("TS: %d/4", pEv->parameter); pos.x -= MFFont_GetStringWidth(pText, pString, 24.0f); pos.y -= 12.0f; MFFont_DrawTextf(pText, pos, 24.0f, MFVector::yellow, pString); } } pEv = pEv->Next(); } // render events pEv = pSong->events.GetNextEvent(bottomTick); int lastChecked = -1; float yEventOffset = -12.0f; while(pEv && pEv->time < topTimeus) { float evTime = GETSECONDS(pEv->time); if(evTime > bottomTime) { if(pEv->event == GHE_Event) { if(lastChecked != pEv->tick) { yEventOffset = -12.0f; lastChecked = pEv->tick; if(pSong->sync.FindEvent(GHE_TimeSignature, pEv->tick, 0)) { yEventOffset -= 24.0f; } } float position = (evTime - time) * scrollSpeed; MFVector pos; MFView_TransformPoint3DTo2D(MakeVector(-halfFB - 0.2f, 0.0f, position), &pos); if(!MFString_CompareN(pEv->GetString(), "section ", 8)) { // draw a line across? pos.x -= MFFont_GetStringWidth(pText, &pEv->GetString()[8], 24.0f); pos.y += yEventOffset; MFFont_DrawTextf(pText, pos, 24.0f, MFVector::blue, &pEv->GetString()[8]); } else { pos.x -= MFFont_GetStringWidth(pText, pEv->GetString(), 24.0f); pos.y += yEventOffset; MFFont_DrawTextf(pText, pos, 24.0f, MFVector::white, pEv->GetString()); } yEventOffset -= 24.0f; } } pEv = pEv->Next(); } // render track events pEv = pSong->notes[track].GetNextEvent(bottomTick); lastChecked = -1; yEventOffset = -12.0f; while(pEv && pEv->time < topTimeus) { float evTime = GETSECONDS(pEv->time); if(evTime > bottomTime) { if(pEv->event == GHE_Event) { if(lastChecked != pEv->tick) { yEventOffset = -12.0f; lastChecked = pEv->tick; if(pSong->sync.FindEvent(GHE_TimeSignature, pEv->tick, 0)) { yEventOffset -= 24.0f; } GHEvent *pOther = pSong->events.FindEvent(GHE_Event, pEv->tick, 0); while(pOther && pOther->tick == pEv->tick) { yEventOffset -= 24.0f; pOther = pOther->Next(); } } float position = (evTime - time) * scrollSpeed; MFVector pos; MFView_TransformPoint3DTo2D(MakeVector(-halfFB - 0.2f, 0.0f, position), &pos); pos.x -= MFFont_GetStringWidth(pText, pEv->GetString(), 24.0f); pos.y += yEventOffset; MFFont_DrawTextf(pText, pos, 24.0f, MakeVector(0.6f, 0.8f, 1.0f, 1.0f), pEv->GetString()); yEventOffset -= 24.0f; } } pEv = pEv->Next(); } MFView_Pop(); }
MF_API void MFModel_Draw(MFModel *pModel) { MFCALLSTACK; MFMatrix *pAnimMats = NULL; MFMatrix wts; if(pModel->pAnimation) { pAnimMats = MFAnimation_CalculateMatrices(pModel->pAnimation, &pModel->worldMatrix); wts = MFView_GetWorldToScreenMatrix(); } else { MFView_GetLocalToScreen(pModel->worldMatrix, &wts); } MFRenderer_SetMatrices(pAnimMats, pAnimMats ? pModel->pAnimation->numBones : 0); MFRendererPC_SetWorldToScreenMatrix(wts); MFRendererPC_SetModelColour(pModel->modelColour); MFMaterial *pMatOverride = (MFMaterial*)MFRenderer_GetRenderStateOverride(MFRS_MaterialOverride); if(pMatOverride) MFMaterial_SetMaterial(pMatOverride); MFModelDataChunk *pChunk = MFModel_GetDataChunk(pModel->pTemplate, MFChunkType_SubObjects); if(pChunk) { MFModelSubObject *pSubobjects = (MFModelSubObject*)pChunk->pData; for(int a=0; a<pChunk->count; a++) { for(int b=0; b<pSubobjects[a].numMeshChunks; b++) { MFMeshChunk_Generic *pMC = (MFMeshChunk_Generic*)pSubobjects[a].pMeshChunks; if(!pMatOverride) MFMaterial_SetMaterial(pMC[b].pMaterial); if(pModel->pAnimation) { MFRendererPC_SetNumWeights(pMC[b].maxBlendWeights); MFRenderer_SetBatch(pMC[b].pBatchIndices, pMC[b].matrixBatchSize); } else MFRendererPC_SetNumWeights(0); MFRenderer_Begin(); MeshChunkD3DRuntimeData &runtimeData = (MeshChunkD3DRuntimeData&)pMC[b].runtimeData; pd3dDevice->SetVertexDeclaration(runtimeData.vertexDecl); pd3dDevice->SetStreamSource(0, runtimeData.vertexBuffer, 0, pMC[b].pVertexFormat->pStreams[0].streamStride); if(runtimeData.animBuffer) pd3dDevice->SetStreamSource(1, runtimeData.animBuffer, 0, pMC[b].pVertexFormat->pStreams[1].streamStride); pd3dDevice->SetIndices(runtimeData.indexBuffer); pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, pMC[b].numVertices, 0, pMC[b].numIndices/3); } } } }