//-----------------------------------------------------------------------------
// File: Render.cpp
//
// Desc: Frame move and render
//
// Note: This code uses the D3D Framework helper library.
//
//
// Copyright (c) 2001 Black Sphere Corp.
//-----------------------------------------------------------------------------
#define STRICT
#define D3D_OVERLOADS
#include "render.h"
//-----------------------------------------------------------------------------
// Declare the application globals for use in WinMain.cpp
//-----------------------------------------------------------------------------
TCHAR* g_strAppTitle = TEXT( "Black Sphere Corp. 3D Screen Saver" );
BOOL g_bAppUseZBuffer = TRUE; // Create/use a z-buffer
//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define LERP(m,x0,x1) ((x0) + (m)*((x1)-(x0)))
#define PI 3.14159265358979323846f
#define ELLIPSE_RADIUS 1.5f
#define ELLIPSE_NUMRINGS 20
#define ELLIPSE_NUMSECTIONS 20
#define ELLIPSE_X_LENGTH 1.0f
#define ELLIPSE_Y_LENGTH 3.0f
#define ELLIPSE_Z_LENGTH 1.0f
D3DVERTEX* g_pvModelVertices1 = NULL; //object's vertices
D3DVERTEX* g_pvModelVertices2 = NULL; //object's vertices
D3DVERTEX* g_pvRenderVertices = NULL; //object's vertices
WORD* g_pwRenderIndices = NULL; //object's indices
DWORD g_dwNumVertices;
DWORD g_dwNumIndices;
CD3DFile* g_pPP1Object = NULL;
CD3DFile* g_pPP2Object = NULL;
CD3DFile* g_pPP3Object = NULL;
CD3DFile* g_pPP4Object = NULL;
D3DMATRIX g_matPP1Matrix;
D3DMATRIX g_matPP2Matrix;
D3DMATRIX g_matPP3Matrix;
D3DMATRIX g_matPP4Matrix;
CD3DFile* g_pSphereObject = NULL;
D3DMATRIX g_matSphereMatrix;
HRESULT hr;
//DWORD dwCoopFlags;
//RECT rc;
DWORD dwRenderWidth;
DWORD dwRenderHeight;
D3DVIEWPORT7 vp;
//DDSURFACEDESC2 ddsd;
//LPDIRECTDRAWSURFACE7 pddsCoverSurface;
//LPDIRECTDRAWCLIPPER pcClipper;
//D3DMATRIX matBsc;
// D3DMATRIX matView;
// D3DVECTOR vEyePt = D3DVECTOR( 0.0f, 0.0f, 0.0f );
// D3DVECTOR vLookatPt = D3DVECTOR( 0.0f, 0.0f, 1.0f );
// D3DVECTOR vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f );
D3DXMATRIX matAll;
D3DXMATRIX matTrans;
D3DXMATRIX matScale;
D3DXMATRIX matRot;
D3DXQUATERNION qRot;
float fX = 0.0f;
float fY = 0.0f;
float fZ = 0.0f;
float fRadsX = 0.0f;
float fRadsY = 0.0f;
float fRadsZ = 0.0f;
bool moveXUpPP1 = true;
bool moveYUpPP1 = true;
bool moveZUpPP1 = true;
bool moveXUpPP2 = true;
bool moveYUpPP2 = true;
bool moveZUpPP2 = true;
bool moveXUpPP3 = true;
bool moveYUpPP3 = true;
bool moveZUpPP3 = true;
bool moveXUpPP4 = true;
bool moveYUpPP4 = true;
bool moveZUpPP4 = true;
//bool bLButtonDown = false;
//bool bRButtonDown = false;
bool bHitRightPP1 = false;
bool bHitRightPP2 = false;
bool bHitRightPP3 = false;
bool bHitRightPP4 = false;
// alpha-blending
int iAlpha1 = 0;
int iAlpha2 = 0;
bool fadeIn1 = true;
bool fadeIn2 = false;
int count1 = 0;
int count2 = 0;
bool bStartTumble = false;
int i = 0;
bool tumblePP1 = true;
bool tumblePP2 = true;
bool tumblePP3 = true;
bool tumblePP4 = true;
float fAspect;
D3DMATRIX matProj;
//bool bRenderTargetTooSmall = false;
// options
// TODO: put these in ScreenSaverOptions struct
float g_fSpeed;
float g_fRotation;
// NOTE: using BOOL (i.e. int) instead of bool will prevent C4800 warnings when
// assigning it a DWORD reg value
BOOL g_bSound = false;
BOOL g_bShowTrace = false;
float g_fXLimit;
float g_fYLimit;
float g_fZLimit;
float fRandomPP1DeltaX = 0.0f;
float fRandomPP1DeltaY = 0.0f;
float fRandomPP2DeltaX = 0.0f;
float fRandomPP2DeltaY = 0.0f;
float fRandomPP3DeltaX = 0.0f;
float fRandomPP3DeltaY = 0.0f;
float fRandomPP4DeltaX = 0.0f;
float fRandomPP4DeltaY = 0.0f;
int iRandomPP1X = 0;
int iRandomPP1Y = 0;
int iRandomPP2X = 0;
int iRandomPP2Y = 0;
int iRandomPP3X = 0;
int iRandomPP3Y = 0;
int iRandomPP4X = 0;
int iRandomPP4Y = 0;
extern CD3DFramework7* g_pFramework;
void TumblePP( D3DMATRIX& matPP, bool& moveXUp, bool& moveYUp, bool& bHitRight,
int& iRandomX, int& iRandomY, float& fRandomDeltaX, float& fRandomDeltaY );
void DrawLogo();
void DrawLogo1( LPDIRECT3DDEVICE7 pd3dDevice);
void DrawLogo2( LPDIRECT3DDEVICE7 pd3dDevice);
void DrawLogo3( LPDIRECT3DDEVICE7 pd3dDevice);
void DrawLogo4( LPDIRECT3DDEVICE7 pd3dDevice);
void BltAlphaFactor( LPDIRECT3DDEVICE7 pdev, LPDIRECTDRAWSURFACE7 pTex,
WORD x, WORD y, WORD x2, WORD y2, BYTE factor, bool clear );
// textures
//enum {
// TEX_SPHERE0, TEX_SPHERE1, TEX_SPHERE2, TEX_SPHERE3,
// NUM_TEXTURES
//};
char* g_szTexName[NUM_TEXTURES];
LPDIRECTDRAWSURFACE7 g_ppTex[NUM_TEXTURES];
//-----------------------------------------------------------------------------
// Function prototypes and global (or static) variables
//-----------------------------------------------------------------------------
VOID AppPause( BOOL );
VOID RotateVertexInX( FLOAT, DWORD, D3DVERTEX*, D3DVERTEX* );
BOOL GenerateSphere( FLOAT, DWORD, DWORD, FLOAT, FLOAT, FLOAT, D3DVERTEX**,
DWORD*, WORD**, DWORD* );
VOID BlendObjects( DWORD, D3DVERTEX*, D3DVERTEX*, D3DVERTEX* );
//-----------------------------------------------------------------------------
// Name: App_OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
// permanent initialization.
//-----------------------------------------------------------------------------
HRESULT App_OneTimeSceneInit()
{
/*
// Generate the object data
GenerateSphere( ELLIPSE_RADIUS, ELLIPSE_NUMRINGS, ELLIPSE_NUMSECTIONS,
ELLIPSE_X_LENGTH, ELLIPSE_Y_LENGTH, ELLIPSE_Z_LENGTH,
&g_pvRenderVertices, &g_dwNumVertices,
&g_pwRenderIndices, &g_dwNumIndices );
RotateVertexInX( (FLOAT)(PI/2), g_dwNumVertices, g_pvRenderVertices,
g_pvRenderVertices );
// Make two copies of the object (for modification of the vertices)
g_pvModelVertices1 = new D3DVERTEX[g_dwNumVertices];
g_pvModelVertices2 = new D3DVERTEX[g_dwNumVertices];
for( DWORD i=0; i < g_dwNumVertices; i++ )
{
g_pvModelVertices1[i] = g_pvRenderVertices[i];
g_pvModelVertices2[i] = g_pvRenderVertices[i];
}
// Create textures
//D3DTextr_CreateTextureFromFile( "Banana.bmp" );
// ??? No
//D3DTextr_CreateTextureFromFile( "IDB_BITMAP1" );
//D3DTextr_CreateTextureFromFile( "IDB_BITMAP2" );
//D3DTextr_RestoreAllTextures( pd3dDevice );
*/
// kludge
//SetCurrentDirectory( "C:\\resources" );
//SetCurrentDirectory( "..\\media" );
//SetCurrentDirectory( "F:\\mssdk\\samples\\Multimedia\\D3DIM\\src\\ScreenSaver\\media" );
SetCurrentDirectory( g_strMediaPath );
// Scr should be self-contained app, i.e. a single file. Therefore the
// textures should be resources, and the x file too. On app start up we
// first create files from the resources and scr loads these
// Create the files in C:\ because it would be ugly for the user to see
// all those files being created when double-clicking the scr (or would it)
// Delete the files after the scr exits.
// Geen self-contained app: zo krijgt user kans wat met de media files te spelen.
// InstallShield en save program directory in reg zodat scr de media dir kan vinden.
// Load the pilot position marks
g_pPP1Object = new CD3DFile();
if( FAILED( g_pPP1Object->Load( "pp1.x" ) ) ) {
MessageBox(NULL,"Can't find X file.",
"Black Sphere Corp. 3D Screensaver Error Message",MB_OK|MB_ICONERROR);
return E_FAIL;
}
// Load the pilot position marks
g_pPP2Object = new CD3DFile();
if( FAILED( g_pPP2Object->Load( "pp2.x" ) ) ) {
MessageBox(NULL,"Can't find X file.",
"Black Sphere Corp. 3D Screensaver Error Message",MB_OK|MB_ICONERROR);
return E_FAIL;
}
// Load the pilot position marks
g_pPP3Object = new CD3DFile();
if( FAILED( g_pPP3Object->Load( "pp3.x" ) ) ) {
MessageBox(NULL,"Can't find X file.",
"Black Sphere Corp. 3D Screensaver Error Message",MB_OK|MB_ICONERROR);
return E_FAIL;
}
// Load the pilot position marks
g_pPP4Object = new CD3DFile();
if( FAILED( g_pPP4Object->Load( "pp4.x" ) ) ) {
MessageBox(NULL,"Can't find X file.",
"Black Sphere Corp. 3D Screensaver Error Message",MB_OK|MB_ICONERROR);
return E_FAIL;
}
// Load the sphere
g_pSphereObject = new CD3DFile();
if( FAILED( g_pSphereObject->Load( "sphere.x" ) ) ) {
MessageBox(NULL,"Can't find X file.",
"Black Sphere Corp. 3D Screensaver Error Message",MB_OK|MB_ICONERROR);
return E_FAIL;
}
// set matrix
D3DUtil_SetIdentityMatrix(g_matPP1Matrix);
D3DUtil_SetScaleMatrix(matScale, g_CurrentOptions.fSize, g_CurrentOptions.fSize, g_CurrentOptions.fSize);
D3DMath_MatrixMultiply(g_matPP1Matrix, matScale, g_matPP1Matrix); // order is crucial!!!
g_matPP1Matrix._41 = -15.0f;
g_matPP1Matrix._43 = g_CurrentOptions.fZoom; //2.0f;
g_matPP2Matrix=g_matPP3Matrix=g_matPP4Matrix=g_matPP1Matrix;
//g_matPP2Matrix._41 = -20.0f;
//g_matPP3Matrix._41 = -30.0f;
//g_matPP4Matrix._41 = -40.0f;
// logo4 sphere
D3DUtil_SetIdentityMatrix(g_matSphereMatrix);
float fScale = 0.92f; //0.9f;
D3DUtil_SetScaleMatrix(matScale, 1.0f*fScale, 1.25f*fScale, 1.0f*fScale);
D3DMath_MatrixMultiply(g_matSphereMatrix, matScale, g_matSphereMatrix); // order is crucial!!!
D3DUtil_SetRotateZMatrix(matRot, -g_PI_DIV_2-0.3f);
D3DMath_MatrixMultiply(g_matSphereMatrix, matRot, g_matSphereMatrix);
g_matSphereMatrix._43 = 0.0f; //0.0f;
// Seed the random-number generator with current time so that
// the numbers will be different every time we run.
srand( (unsigned)time( NULL ) );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: App_FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT App_FrameMove( LPDIRECT3DDEVICE7 pd3dDevice, FLOAT fTimeKey )
{
// Compute the bend and rotate angles for this frame
FLOAT fRotateAngle = (FLOAT)( fTimeKey / 3 );
FLOAT fBendAngle = (FLOAT)( (sin(fTimeKey)+1.0f)*0.6f );
// Setup the world spin matrix
D3DMATRIX matWorldSpin;
D3DUtil_SetRotateYMatrix( matWorldSpin, fRotateAngle );
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorldSpin );
if (g_CurrentOptions.bGameLoop) {
// gameloop
g_fSpeed = g_CurrentOptions.fSpeed*3; // 0.1f;
g_fRotation = g_CurrentOptions.fRotation*10; // 0.34f;
} else {
// timerloop
g_fSpeed = g_CurrentOptions.fSpeed*6; // 0.2f;
g_fRotation = g_CurrentOptions.fRotation*20; // 1.0f;
}
// kludge for cursor
if (g_CurrentOptions.bGameLoop) {
//SetCursor(NULL);
//ShowCursor( FALSE );
}
g_bSound = g_CurrentOptions.bSound;
g_fXLimit = 6.5f;
g_fYLimit = 6.5f;
//g_fZLimit = 8.0f;
// Mmm, nothing like a proper gameloop: timer causes erratic framerate
// In 3D About Box not really noticable but here unacceptable
//MessageBeep(-1);
// tumble PP1
if (tumblePP1 && g_CurrentOptions.bMark1)
TumblePP( g_matPP1Matrix, moveXUpPP1, moveYUpPP1, bHitRightPP1,
iRandomPP1X, iRandomPP1Y, fRandomPP1DeltaX, fRandomPP1DeltaY );
// tumble PP2
if (tumblePP2 && g_CurrentOptions.bMark2)
TumblePP( g_matPP2Matrix, moveXUpPP2, moveYUpPP2, bHitRightPP2,
iRandomPP2X, iRandomPP2Y, fRandomPP2DeltaX, fRandomPP2DeltaY );
// tumble PP3
if (tumblePP3 && g_CurrentOptions.bMark3)
TumblePP( g_matPP3Matrix, moveXUpPP3, moveYUpPP3, bHitRightPP3,
iRandomPP3X, iRandomPP3Y, fRandomPP3DeltaX, fRandomPP3DeltaY );
// tumble PP4
if (tumblePP4 && g_CurrentOptions.bMark4)
TumblePP( g_matPP4Matrix, moveXUpPP4, moveYUpPP4, bHitRightPP4,
iRandomPP4X, iRandomPP4Y, fRandomPP4DeltaX, fRandomPP4DeltaY );
// Bend two copies of the object in different directions and
// merge (blend) them into one set of vertex data.
//RotateVertexInX( fBendAngle, g_dwNumVertices, g_pvModelVertices2,
// g_pvModelVertices1 );
//BlendObjects( g_dwNumVertices, g_pvModelVertices1, g_pvModelVertices2,
// g_pvRenderVertices );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: App_Render()
// Desc: Called once per frame, the call is the entry point for 3d
// rendering. This function sets up render states, clears the
// viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT App_Render( LPDIRECT3DDEVICE7 pd3dDevice )
{
// TODO: only in timerloop will scr be visible in Display Properties
// but when moving that dialog scr will be fucked. This is a bug in the
// original app. Fix it!!!
// TODO: solve artifacts in gameloop:
// - not visible in Display Properties
// - desktop flickers through
// - cursor shows
// - mousemove does not kill saver
// - when Display Properties dialog is up and scr appears after the
// set minutes have elapsed scr will be very slow and erratic
// NOTE: mousemove does kill scr when in game loop if we are in another resolution
// than 640x480 and let the scr run at 640x480
//
// NOTE2: 640x480x16 is de veiligste mode
// trace werkt alleen goed in 640x480x16 + gameloop
// Don't switch trace on here, or logos will be painted incorrectly
// switch it on when we start tumbling
//g_bShowTrace = g_CurrentOptions.bTrace;
// Clear the viewport
if (g_bShowTrace) {
pd3dDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER,
0x00000000, 1.0f, 0L ); // black
} else {
pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0x00000000, 1.0f, 0L ); // black
}
// GDI blitting is too slow...///////////////////////////////////////
//if (g_CurrentOptions.bLogo)
// DrawLogo();
/////////////////////////////////////////////////////////////////////
// TODO: draw black background with DrawPrimitive()
// TODO: draw bsc logo with DrawPrimitive()
// But make sure your textures are square and a power of 2
// De juiste D3D manier van bitmap drawing (GDI Blt is too slow):
// See: Flare Sample
// Draw the background
// m_pd3dDevice->SetTexture( 0, D3DTextr_GetSurface("dx5_logo.bmp") );
// m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX,
// m_Background, 4, 0 );
//Sleep(100);
//SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS );
//SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS );
// Begin the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
//Display the object
//pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, D3DFVF_VERTEX,
// g_pvRenderVertices, g_dwNumVertices,
// g_pwRenderIndices, g_dwNumIndices, NULL );
if( !g_CurrentOptions.bShowLogo ) {
g_CurrentOptions.bLogo1 = false;
g_CurrentOptions.bLogo2 = false;
g_CurrentOptions.bLogo3 = false;
g_CurrentOptions.bLogo4 = false;
bStartTumble = true;
}
// D3D blitting for raw speed.../////////////////////////////////////
if (g_CurrentOptions.bLogo1) DrawLogo1( pd3dDevice );
/////////////////////////////////////////////////////////////////////
// D3D blitting for raw speed.../////////////////////////////////////
if (g_CurrentOptions.bLogo2) DrawLogo2( pd3dDevice );
/////////////////////////////////////////////////////////////////////
// D3D blitting for raw speed.../////////////////////////////////////
if (g_CurrentOptions.bLogo3) DrawLogo3( pd3dDevice );
/////////////////////////////////////////////////////////////////////
// D3D blitting for raw speed.../////////////////////////////////////
if (g_CurrentOptions.bLogo4) DrawLogo4( pd3dDevice );
/////////////////////////////////////////////////////////////////////
tumblePP1=tumblePP2=tumblePP3=tumblePP4=false;
if (bStartTumble) {
static int count = 0;
count++;
if (count > 0) tumblePP1 = true;
if (count > 111) tumblePP2 = true;
if (count > 222) tumblePP3 = true;
if (count > 333) tumblePP4 = true;
// only now, after logo painting, switch on trace (if user has set it)
g_bShowTrace = g_CurrentOptions.bTrace;
}
//pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP );
// xfile sphere
if ( g_CurrentOptions.bLogo4 ) {
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matSphereMatrix );
g_pSphereObject->Render( pd3dDevice );
}
if ( g_CurrentOptions.bMark1 && g_matPP1Matrix._41 > -(g_fXLimit+1.0f) ) {
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matPP1Matrix );
g_pPP1Object->Render( pd3dDevice );
}
if ( g_CurrentOptions.bMark2 && g_matPP2Matrix._41 > -(g_fXLimit+1.0f) ) {
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matPP2Matrix );
g_pPP2Object->Render( pd3dDevice );
}
if ( g_CurrentOptions.bMark3 && g_matPP3Matrix._41 > -(g_fXLimit+1.0f) ) {
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matPP3Matrix );
g_pPP3Object->Render( pd3dDevice );
}
if ( g_CurrentOptions.bMark4 && g_matPP4Matrix._41 > -(g_fXLimit+1.0f) ) {
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &g_matPP4Matrix );
g_pPP4Object->Render( pd3dDevice );
}
// End the scene.
pd3dDevice->EndScene();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: App_InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT App_InitDeviceObjects( HWND hWnd, LPDIRECT3DDEVICE7 pd3dDevice )
{
// Check parameters
if( NULL==pd3dDevice )
return E_INVALIDARG;
// Get the device caps
D3DDEVICEDESC7 ddDesc;
if( FAILED( pd3dDevice->GetCaps( &ddDesc ) ) )
return E_FAIL;
// Setup the material
D3DMATERIAL7 mtrl;
D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
mtrl.power = 40.0f;
pd3dDevice->SetMaterial( &mtrl );
// Set up the textures
D3DTextr_RestoreAllTextures( pd3dDevice );
pd3dDevice->SetTexture( 0, D3DTextr_GetSurface("Banana.bmp") );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR );
pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR );
// new textures
// NOTE: got to set the current directory right
//
// CD3DFile::Load() searches as follows:
// 1. D3DUtil_GetDXSDKMediaPath()
// 2. current directory
//
// D3DTextr_CreateTextureFromFile() searches are done by:
// TextureContainer::LoadImageData() as follows:
// 1. executable's resource (so it must be possible to put all the bmp's in the .exe)
// 2. current directory/global texture path (can be set by D3DTextr_SetTexturePath(),
// initially set to current directory)
// 3. D3DUtil_GetDXSDKMediaPath()
// already there
//SetCurrentDirectory( "..\\media" );
D3DTextr_CreateTextureFromFile( "sphere0.bmp" );
D3DTextr_CreateTextureFromFile( "sphere1.bmp" );
//D3DTextr_CreateTextureFromFile( "sphere2.bmp" );
//D3DTextr_CreateTextureFromFile( "sphere3.bmp" );
D3DTextr_RestoreAllTextures( pd3dDevice );
g_ppTex[TEX_SPHERE0] = D3DTextr_GetSurface( "sphere0.bmp" );
g_ppTex[TEX_SPHERE1] = D3DTextr_GetSurface( "sphere1.bmp" );
//g_ppTex[TEX_SPHERE2] = D3DTextr_GetSurface( "sphere2.bmp" );
//g_ppTex[TEX_SPHERE3] = D3DTextr_GetSurface( "sphere3.bmp" );
// Miscellaneous render states
pd3dDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0x40404040 );
pd3dDevice->SetRenderState( D3DRENDERSTATE_DITHERENABLE, TRUE );
pd3dDevice->SetRenderState( D3DRENDERSTATE_SPECULARENABLE, TRUE );
pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE );
// Set the transform matrices
D3DVECTOR vEyePt = D3DVECTOR( 0.0f, 0.0f, -6.5f );
D3DVECTOR vLookatPt = D3DVECTOR( 0.0f, 0.0f, 0.0f );
D3DVECTOR vUpVec = D3DVECTOR( 0.0f, 1.0f, 0.0f );
D3DMATRIX matWorld, matView, matProj;
D3DUtil_SetIdentityMatrix( matWorld );
D3DUtil_SetViewMatrix( matView, vEyePt, vLookatPt, vUpVec );
D3DUtil_SetProjectionMatrix( matProj, 1.57f, 1.0f, 1.0f, 100.0f );
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_WORLD, &matWorld );
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_VIEW, &matView );
pd3dDevice->SetTransform( D3DTRANSFORMSTATE_PROJECTION, &matProj );
// Set up lighting states
if( ddDesc.dwVertexProcessingCaps & D3DVTXPCAPS_DIRECTIONALLIGHTS )
{
D3DLIGHT7 light;
D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, 0.0f, -1.0f, 0.0f );
pd3dDevice->SetLight( 0, &light );
pd3dDevice->LightEnable( 0, TRUE );
pd3dDevice->SetRenderState( D3DRENDERSTATE_LIGHTING, TRUE );
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: App_DeleteDeviceObjects()
// Desc: Called when the app is exitting, or the device is being changed,
// this function deletes any device dependant objects.
//-----------------------------------------------------------------------------
VOID App_DeleteDeviceObjects( HWND hWnd, LPDIRECT3DDEVICE7 pd3dDevice )
{
D3DTextr_InvalidateAllTextures();
}
//-----------------------------------------------------------------------------
// Name: App_FinalCleanup()
// Desc: Called before the app exits, this function gives the app the chance
// to cleanup after itself.
//-----------------------------------------------------------------------------
HRESULT App_FinalCleanup()
{
SAFE_DELETE( g_pvModelVertices1 );
SAFE_DELETE( g_pvModelVertices2 );
SAFE_DELETE( g_pvRenderVertices );
SAFE_DELETE( g_pwRenderIndices );
return S_OK;
}
//----------------------------------------------------------------------------
// Name: App_RestoreSurfaces
// Desc: Restores any previously lost surfaces. Must do this for all surfaces
// (including textures) that the app created.
//----------------------------------------------------------------------------
HRESULT App_RestoreSurfaces()
{
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: App_ConfirmDevice()
// Desc: Called during device intialization, this code checks the device
// for some minimum set of capabilities
//-----------------------------------------------------------------------------
HRESULT App_ConfirmDevice( DDCAPS* pddDriverCaps,
D3DDEVICEDESC7* pd3dDeviceDesc )
{
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RotateVertexInX()
// Desc: Rotates an array of vertices by an amount theta about the x-axis.
//-----------------------------------------------------------------------------
VOID RotateVertexInX( FLOAT fTheta, DWORD dwCount,
D3DVERTEX* pvInVertices, D3DVERTEX* pvOutVertices )
{
FLOAT fSin = (FLOAT)sin(fTheta);
FLOAT fCos = (FLOAT)cos(fTheta);
for( DWORD i=0; i < dwCount; i++ )
{
FLOAT y = pvInVertices[i].y;
FLOAT z = pvInVertices[i].z;
pvOutVertices[i].y = fCos*y + fSin*z;
pvOutVertices[i].z = -fSin*y + fCos*z;
FLOAT ny = pvInVertices[i].ny;
FLOAT nz = pvInVertices[i].nz;
pvOutVertices[i].ny = fCos*ny + fSin*nz;
pvOutVertices[i].nz = -fSin*ny + fCos*nz;
}
}
//-----------------------------------------------------------------------------
// Name: GenerateSphere()
// Desc: Makes vertex and index data for a sphere.
//-----------------------------------------------------------------------------
BOOL GenerateSphere( FLOAT fRadius, DWORD dwNumRings, DWORD dwNumSections,
FLOAT sx, FLOAT sy, FLOAT sz,
D3DVERTEX** ppvVertices, DWORD* pdwNumVertices,
WORD** ppwIndices, DWORD* pdwNumIndices )
{
FLOAT x, y, z, v, rsintheta; // Temporary variables
DWORD i, j; // counters
DWORD n, m; // counters
//Generate space for the required triangles and vertices.
DWORD dwNumTriangles = (dwNumRings+1) * dwNumSections * 2;
DWORD dwNumVertices = (dwNumRings+1) * dwNumSections + 2;
D3DVERTEX* pvVertices = new D3DVERTEX[dwNumVertices];
DWORD dwNumIndices = dwNumTriangles*3;
WORD* pwIndices = new WORD[dwNumIndices];
// Generate vertices at the top and bottom points.
D3DVECTOR vPoint = D3DVECTOR( 0.0f, sy*fRadius, 0.0f );
D3DVECTOR vNormal = D3DVECTOR( 0.0f, 0.0f, 1.0f );
pvVertices[0] = D3DVERTEX( vPoint, vNormal, 0.0f, 0.0f );
pvVertices[dwNumVertices-1] = D3DVERTEX( -vPoint, -vNormal, 0.0f, 0.0f );
// Generate vertex points for rings
FLOAT dtheta = (FLOAT)(PI / (dwNumRings + 2)); //Angle between each ring
FLOAT dphi = (FLOAT)(2*PI / dwNumSections); //Angle between each section
FLOAT theta = dtheta;
n = 1; //vertex being generated, begins at 1 to skip top point
dwNumRings += 1;
dwNumRings -= 1;
for( i = 0; i < (dwNumRings+1); i++ )
{
y = fRadius * (FLOAT)cos(theta); // y is the same for each ring
v = theta / PI; // v is the same for each ring
rsintheta = fRadius * (FLOAT)sin(theta);
FLOAT phi = 0.0f;
for( j = 0; j < dwNumSections; j++ )
{
x = rsintheta * (FLOAT)sin(phi);
z = rsintheta * (FLOAT)cos(phi);
FLOAT u = (FLOAT)(1.0 - phi / (2*PI) );
vPoint = D3DVECTOR( sx*x, sy*y, sz*z );
vNormal = D3DVECTOR( x/fRadius, y/fRadius, z/fRadius );
pvVertices[n] = D3DVERTEX( vPoint, vNormal, u, v );
phi += dphi;
++n;
}
theta += dtheta;
}
// Generate triangles for top and bottom caps.
for( i = 0; i < dwNumSections; i++ )
{
DWORD t1 = 3*i;
DWORD t2 = 3*(dwNumTriangles - dwNumSections + i);
pwIndices[t1+0] = (WORD)(0);
pwIndices[t1+1] = (WORD)(i + 1);
pwIndices[t1+2] = (WORD)(1 + ((i + 1) % dwNumSections));
pwIndices[t2+0] = (WORD)( dwNumVertices - 1 );
pwIndices[t2+1] = (WORD)( dwNumVertices - 2 - i );
pwIndices[t2+2] = (WORD)( dwNumVertices - 2 - ((1 + i) % dwNumSections) );
}
// Generate triangles for the rings
m = 1; // 1st vertex begins at 1 to skip top point
n = dwNumSections; // triangle being generated, skip the top cap
for( i = 0; i < dwNumRings; i++ )
{
for( j = 0; j < dwNumSections; j++ )
{
pwIndices[3*n+0] = (WORD)(m + j);
pwIndices[3*n+1] = (WORD)(m + dwNumSections + j);
pwIndices[3*n+2] = (WORD)(m + dwNumSections + ((j + 1) % dwNumSections));
n++;
pwIndices[3*n+0] = (WORD)(m + j);
pwIndices[3*n+1] = (WORD)(m + dwNumSections + ((j + 1) % dwNumSections));
pwIndices[3*n+2] = (WORD)(m + ((j + 1) % dwNumSections));
n++;
}
m += dwNumSections;
}
(*pdwNumIndices) = dwNumIndices;
(*ppwIndices) = pwIndices;
(*pdwNumVertices) = dwNumVertices;
(*ppvVertices) = pvVertices;
return TRUE;
}
//-----------------------------------------------------------------------------
// Name: BlendObjects()
// Desc: Merges two sets of vertices together
//-----------------------------------------------------------------------------
VOID BlendObjects( DWORD dwCount, D3DVERTEX* pvInputVertices1,
D3DVERTEX* pvInputVertices2,
D3DVERTEX* pvOutputVertices )
{
D3DVERTEX* p1 = pvInputVertices1;
D3DVERTEX* p2 = pvInputVertices2;
D3DVERTEX* p3 = pvOutputVertices;
FLOAT fMinZ = -ELLIPSE_Y_LENGTH * ELLIPSE_RADIUS;
FLOAT fMaxZ = +ELLIPSE_Y_LENGTH * ELLIPSE_RADIUS;
for( DWORD i=0; iz - fMinZ ) / ( fMaxZ - fMinZ );
if( a >= 0.75f )
m = 0.0f;
else if( a >= 0.5f )
{
FLOAT x = 4*(0.75f-a);
m = (x*x)*0.5f;
}
else if( a >= 0.25f )
{
FLOAT x = 4*(a-0.25f);
m = 1.0f-(x*x)*0.5f;
}
else
m = 1.0f;
p3->x = LERP( m, p1->x, p2->x );
p3->y = LERP( m, p1->y, p2->y );
p3->z = LERP( m, p1->z, p2->z );
p1++; p2++; p3++;
}
}
//-----------------------------------------------------------------------------
// Name: TumblePP()
// Desc: Tumble about PP's
//-----------------------------------------------------------------------------
void TumblePP( D3DMATRIX& matPP, bool& moveXUp, bool& moveYUp, bool& bHitRight,
int& iRandomX, int& iRandomY, float& fRandomDeltaX, float& fRandomDeltaY )
{
// X
if (moveXUp)
matPP._41 += g_fSpeed;
else
matPP._41 -= g_fSpeed;
if (matPP._41 > g_fXLimit) {
moveXUp = false;
bHitRight = true;
if (g_bSound)
PlaySound( "crash.wav", NULL, SND_FILENAME|SND_ASYNC );
}
if (matPP._41 < -g_fXLimit) {
moveXUp = true;
if (g_bSound && bHitRight)
PlaySound( "crash.wav", NULL, SND_FILENAME|SND_ASYNC );
}
// Y
if (moveYUp)
matPP._42 += g_fSpeed/2;
else
matPP._42 -= g_fSpeed;
if (matPP._42 > g_fYLimit) {
moveYUp = false;
if (g_bSound)
PlaySound( "crash.wav", NULL, SND_FILENAME|SND_ASYNC );
}
if (matPP._42 < -g_fYLimit) {
moveYUp = true;
if (g_bSound)
PlaySound( "crash.wav", NULL, SND_FILENAME|SND_ASYNC );
}
/*
// Z
if (moveZUp)
matPP._43 += 0.1f;
else
matPP._43 -= 0.1f;
if (matPP._43 > 11.0f) moveZUp = false;
if (matPP._43 < 9.0f) moveZUp = true;
*/
fRadsX = -0.08f*g_fRotation;
fRadsY = -0.15f*g_fRotation;
fRadsZ = -0.2f*g_fRotation;
// ook hier: gimbal lock!!!
// Quaternions ///////////
//D3DXMATRIX matTrans;
//D3DXMatrixTranslation( &matTrans, fX, fY, fZ );
//D3DMath_MatrixMultiply(matBsc, matTrans, matBsc); // order is crucial!!!
//D3DXMATRIX matRot;
//D3DXQUATERNION qRot;
//D3DXQuaternionRotationYawPitchRoll( &qRot, fRadsY, fRadsX, fRadsZ );
//D3DXMatrixRotationQuaternion( &matRot, &qRot );
D3DXMatrixRotationYawPitchRoll( &matRot, fRadsY, fRadsX, fRadsZ );
D3DMath_MatrixMultiply(matPP, matRot, matPP); // order is crucial!!!
// Order!!!
//D3DMath_MatrixMultiply( matBsc, matTrans, matBsc );
//D3DMath_MatrixMultiply( matBsc, matRot, matBsc );
//D3DMath_MatrixMultiply( matAll, matRot, matBsc );
//D3DMath_MatrixMultiply( matBsc, matAll, matBsc );
// reset!!!
fX=fY=fZ=0.0f;
fRadsX=fRadsY=fRadsZ=0.0f;
// randomize //////////////////////////////////////////////////////////////
// Only seed once per app run!!! Do in OneTimeSceneInit()
// Seed the random-number generator with current time so that
// the numbers will be different every time we run.
// generate one rand per hit
// srand( (unsigned)time( NULL ) );
// RAND_MAX == 0x7fff == 32767
float fRandomFactor = g_CurrentOptions.fRandomFactor; // 0.0f to 0.1f
// only start randomizing if we have hit right
if (bHitRight)
{
// randomize X
if ( (matPP._41 > g_fXLimit && moveXUp == false ) || // hit right
(matPP._41 < -g_fXLimit && moveXUp == true) ) // hit left
{
iRandomX = rand();
fRandomDeltaX = ( (float)iRandomX/RAND_MAX )*fRandomFactor;
//MessageBeep(-1);
}
if ( iRandomX%2 == 0 )
matPP._41 += fRandomDeltaX;
else
matPP._41 -= fRandomDeltaX;
// randomize Y
if ( (matPP._42 > g_fYLimit && moveYUp == false ) || // hit top
(matPP._42 < -g_fYLimit && moveYUp == true) ) // hit bottom
{
iRandomY = rand();
fRandomDeltaY = ( (float)iRandomY/RAND_MAX )*fRandomFactor;
//MessageBeep(-1);
}
if ( iRandomY%2 == 0 )
matPP._42 += fRandomDeltaY;
else
matPP._42 -= fRandomDeltaY;
}
///////////////////////////////////////////////////////////////////////////
}
//-----------------------------------------------------------------------------
// Name: DrawLogo()
// Desc: Sluggish GDI
//-----------------------------------------------------------------------------
void DrawLogo()
{
// GDI blitting is too slow...
// only do this once ////////////////////////////////////////////////
// NO: don't blit into desktop as that will f*ck up the screen if
// scr is watched in Display Properties
// So probably cannot do trace...
// blit a black background otherwise trace won't work
// GDI stuff so must do this outside scene
DDSURFACEDESC2 ddsd;
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
g_pFramework->GetRenderSurface()->GetSurfaceDesc(&ddsd);
dwRenderWidth = ddsd.dwWidth;
dwRenderHeight = ddsd.dwHeight;
HDC hdcDest;
g_pFramework->GetRenderSurface()->GetDC(&hdcDest);
//hDC = GetDC(g_hWnd);
HDC hdcBuffer = CreateCompatibleDC(hdcDest);
HBITMAP hbmBack1 = LoadBitmap( g_hInst, MAKEINTRESOURCE(IDB_BITMAP3));
SelectObject(hdcBuffer, hbmBack1);
//static bool firsttime = true;
//if (firsttime) {
// firsttime = false;
BitBlt(hdcDest, (dwRenderWidth-256)/2, (dwRenderHeight-256)/2, 256, 256, hdcBuffer, 0, 0, SRCCOPY );
//}
// and release
g_pFramework->GetRenderSurface()->ReleaseDC(hdcDest); // release!!!
//ReleaseDC(g_hWnd, hdcDest);
// Clean up
DeleteDC( hdcBuffer );
// laat het geheugen niet vollopen...
DeleteObject(hbmBack1);
/////////////////////////////////////////////////////////////////////
}
//-----------------------------------------------------------------------------
// Name: BltAlphaFactor()
// Desc: Draws a textured square which can be used for fade-in/fade out.
// Note: We must be in a scene.
//-----------------------------------------------------------------------------
void BltAlphaFactor( LPDIRECT3DDEVICE7 pdev, LPDIRECTDRAWSURFACE7 pTex,
WORD x, WORD y, WORD x2, WORD y2, BYTE factor, bool clear )
{
D3DTLVERTEX square1[4];
// we zetten de square zover mogelijk naar achter zodat PP1 ervoor blijft
// NOTE: The largest allowable value for dvSZ is 0.99999 if you want the vertex to be
// within the range of z-values that are displayed:
// Z-values are in device space rather than camera space
square1[0]=D3DTLVERTEX( D3DVECTOR(x,y, 0.99999f) ,1.0,RGBA_MAKE(255,255,255,factor),0,0,0 );
square1[1]=D3DTLVERTEX( D3DVECTOR(x2,y, 0.99999f) ,1.0,RGBA_MAKE(255,255,255,factor),0,1,0 );
square1[2]=D3DTLVERTEX( D3DVECTOR(x,y2, 0.99999f) ,1.0,RGBA_MAKE(255,255,255,factor),0,0,1 );
square1[3]=D3DTLVERTEX( D3DVECTOR(x2,y2,0.99999f) ,1.0,RGBA_MAKE(255,255,255,factor),0,1,1 );
// we zetten de square zover mogelijk naar achter zodat PP1 ervoor blijft
// NOTE: The largest allowable value for dvSZ is 0.99999 if you want the vertex to be
// within the range of z-values that are displayed:
// Z-values are in device space rather than camera space
//square1[0]=D3DTLVERTEX( D3DVECTOR(x,y, 0.99999f), 1.0,RGBA_MAKE(0,0,0,factor),0,0,0);
//square1[1]=D3DTLVERTEX( D3DVECTOR(x2,y, 0.99999f), 1.0,RGBA_MAKE(0,0,0,factor),0,1,0);
//square1[2]=D3DTLVERTEX( D3DVECTOR(x,y2, 0.99999f), 1.0,RGBA_MAKE(0,0,0,factor),0,0,1);
//square1[3]=D3DTLVERTEX( D3DVECTOR(x2,y2,0.99999f), 1.0,RGBA_MAKE(0,0,0,factor),0,1,1);
if (clear==true) pdev->Clear(0,NULL,D3DCLEAR_TARGET,0,0.0f,0);
pdev->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,true);
pdev->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCALPHA);
pdev->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_INVSRCALPHA);
pdev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_MODULATE);
pdev->SetTexture(0,pTex);
//if( SUCCEEDED( pdev->BeginScene() ) ) {
pdev->DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_TLVERTEX,square1,4,0);
pdev->SetTexture(0,NULL);
pdev->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,false);
// pdev->EndScene();
//}
}
//-----------------------------------------------------------------------------
// Name: DrawLogo1()
// Desc: Draw BSC logo using D3D blitting
// Note: Must be done in scene
//-----------------------------------------------------------------------------
void DrawLogo1( LPDIRECT3DDEVICE7 pd3dDevice)
{
// alpha blending
if (fadeIn1) {
//count1++;
//if ( count1%2==0 )
iAlpha1++;
}
if (iAlpha1 > 255) {
iAlpha1 = 255;
fadeIn1 = false;
fadeIn2 = true;
}
if (fadeIn2) {
//count2++;
//if ( count2%2==0 )
iAlpha2+=3;
}
if (iAlpha2 > 255) {
iAlpha2 = 255;
fadeIn2 = false;
bStartTumble = true;
}
//static int i = 0;
//if (!fadeIn1 && !fadeIn2)
// i++;
//if (i > 30) tumblePP1 = true;
//static int i = 0;
//static bool up = true;
//if (up) i+=7;
//else i-=1;
//if(i>50) up=false;
//if(i<0) up=true;
// sphere
int x = 580;
int y = 200;
int i = -20;
if ( g_CurrentOptions.bUse640x480Mode ) {
x = 360;
y = 120;
i = -100;
}
// Do D3D blit
if (!g_bShowTrace) {
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE0],
x, y, x+256+i, y+256+i, iAlpha1, false );
} else {
if (!bStartTumble)
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE0],
x, y, x+256+i, y+256+i, iAlpha1, false );
}
// text
x = 150;
y = 450;
i = 315;
if ( g_CurrentOptions.bUse640x480Mode ) {
x = 60;
y = 275;
i = 110;
}
if (!g_bShowTrace) {
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE1],
x, y, x+256+i, y+256+i, iAlpha2, false );
} else {
if (!bStartTumble)
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE1],
x, y, x+256+i, y+256+i, iAlpha2, false );
}
}
//-----------------------------------------------------------------------------
// Name: DrawLogo2()
// Desc: Draw BSC logo using D3D blitting
// Note: Must be done in scene
//-----------------------------------------------------------------------------
void DrawLogo2( LPDIRECT3DDEVICE7 pd3dDevice)
{
// alpha blending
if (fadeIn1) {
count1++;
if ( count1%3==0 )
iAlpha1++;
}
if (iAlpha1 > 255) {
iAlpha1 = 255;
fadeIn1 = false;
fadeIn2 = true;
}
if (fadeIn2) {
//count2++;
//if ( count2%2==0 )
iAlpha2+=2;
}
if (iAlpha2 > 255) {
iAlpha2 = 255;
fadeIn2 = false;
bStartTumble = true;
}
static int j = 0;
static bool up = true;
// pulsate
if (fadeIn1) {
if (up) j+=7;
else j-=1;
if(j>50) up=false;
if(j<0) up=true;
} else {
j = 0;
}
if (g_bSound) {
if (j>54 && up==false)
PlaySound( "p_bang.wav", NULL, SND_FILENAME|SND_ASYNC );
}
// sphere
int x = 400;
int y = 210;
int i = 0;
if ( g_CurrentOptions.bUse640x480Mode ) {
x = 215;
y = 120;
i -= 80;
}
// Do D3D blit
if (!g_bShowTrace) {
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE0],
x-j, y-j, (x+256+i)+j, (y+256+i)+j, iAlpha1, false );
} else {
if (!bStartTumble)
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE0],
x-j, y-j, (x+256+i)+j, (y+256+i)+j, iAlpha1, false );
}
// text
x = 245;
y = 490;
i = 350;
if ( g_CurrentOptions.bUse640x480Mode ) {
x = 110;
y = 300;
i = 180;
}
// Do D3D blit
if (!g_bShowTrace) {
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE1],
x, y, x+256+i, y+256+i, iAlpha2, false );
} else {
if (!bStartTumble)
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE1],
x, y, x+256+i, y+256+i, iAlpha2, false );
}
}
//-----------------------------------------------------------------------------
// Name: DrawLogo3()
// Desc: Draw BSC logo using D3D blitting
// Note: Must be done in scene
//-----------------------------------------------------------------------------
void DrawLogo3( LPDIRECT3DDEVICE7 pd3dDevice)
{
count1++;
// alpha blending
if (fadeIn1) {
if ( count1%2==0 )
iAlpha1++;
}
if (iAlpha1 > 255) {
iAlpha1 = 255;
fadeIn1 = false;
fadeIn2 = true;
}
if (fadeIn2) {
//count2++;
//if ( count2%2==0 )
iAlpha2+=2;
}
if (iAlpha2 > 255) {
iAlpha2 = 255;
fadeIn2 = false;
bStartTumble = true;
}
//iAlpha1 = 255;
static int j = -100;
static bool up = true;
// sphere
static int x1 = 650; //130;
static int y1 = 0; //140;
int i = -80;
//if ( g_CurrentOptions.bUse640x480Mode ) {
// x = 130;
// y = 140;
// i -= 80;
//}
// swoosh in
if (up) {
if ( count1%5==0 )
j+=1;
//if ( count1%4==0 )
x1-=1;
if ( count1%4==0 )
y1+=1;
}
if (x1<130) up=false;
// Do D3D blit
if (!g_bShowTrace) {
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE0],
x1-j, y1-j, (x1+256+i)+j, (y1+256+i)+j, iAlpha1, false );
} else {
if (!bStartTumble)
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE0],
x1-j, y1-j, (x1+256+i)+j, (y1+256+i)+j, iAlpha1, false );
}
// text
int x = 250;
int y = 300;
i = 110;
//if ( g_CurrentOptions.bUse640x480Mode ) {
// x = 250;
// y = 300;
// i = 110;
//}
if (!g_bShowTrace) {
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE1],
x, y, x+256+i, y+256+i, iAlpha2, false );
} else {
if (!bStartTumble)
BltAlphaFactor( pd3dDevice, g_ppTex[TEX_SPHERE1],
x, y, x+256+i, y+256+i, iAlpha2, false );
}
}
//-----------------------------------------------------------------------------
// Name: DrawLogo4()
// Desc: Draw BSC logo using D3D blitting
// Note: Must be done in scene
//-----------------------------------------------------------------------------
void DrawLogo4( LPDIRECT3DDEVICE7 pd3dDevice)
{
static int count = 0;
count++;
if (count>200)
bStartTumble = true;
float fRotation = 1.0f;
fRadsX = 0.02f*fRotation;
//fRadsY = -0.05f*fRotation;
//fRadsZ = -0.2f*fRotation;
// ook hier: gimbal lock!!!
// Quaternions ///////////
//D3DXMATRIX matTrans;
//D3DXMatrixTranslation( &matTrans, fX, fY, fZ );
//D3DMath_MatrixMultiply(matBsc, matTrans, matBsc); // order is crucial!!!
//D3DXMATRIX matRot;
//D3DXQUATERNION qRot;
//D3DXQuaternionRotationYawPitchRoll( &qRot, fRadsY, fRadsX, fRadsZ );
//D3DXMatrixRotationQuaternion( &matRot, &qRot );
D3DXMatrixRotationYawPitchRoll( &matRot, fRadsY, fRadsX, fRadsZ );
D3DMath_MatrixMultiply(g_matSphereMatrix, matRot, g_matSphereMatrix); // order is crucial!!!
// Order!!!
//D3DMath_MatrixMultiply( matBsc, matTrans, matBsc );
//D3DMath_MatrixMultiply( matBsc, matRot, matBsc );
//D3DMath_MatrixMultiply( matAll, matRot, matBsc );
//D3DMath_MatrixMultiply( matBsc, matAll, matBsc );
// reset!!!
fX=fY=fZ=0.0f;
fRadsX=fRadsY=fRadsZ=0.0f;
}