New B3D-like Direct3D9/10 Engine

Miscellaneous Forums/Blitz Showcase/New B3D-like Direct3D9/10 Engine

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

Engine source until now:
;)


#include "dxstdafx.h"
#include "resource.h"


ID3DXFont*              g_pFont = NULL;         // Font for drawing text
ID3DXSprite*            g_pTextSprite = NULL;   // Sprite for batching draw text calls
bool                    g_bShowHelp = true;     // If true, it renders the UI control text
CDXUTDialogResourceManager g_DialogResourceManager; // manager for shared resources of dialogs
CD3DSettingsDlg         g_SettingsDlg;          // Device settings dialog
CDXUTDialog             g_HUD;                  // dialog for standard controls

LPDIRECT3D9             D3D       = NULL;
LPDIRECT3DDEVICE9       Device    = NULL;
LPDIRECT3DSURFACE9		BackBuffer= NULL;

struct D3DVERTEX
{
    D3DXVECTOR3 p;
    D3DXVECTOR3 n;
	DWORD c;
    FLOAT       tu, tv;
	
    static const DWORD FVF;
};
const DWORD D3DVERTEX::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1;



struct CAMERA
{
	int ViewportX;
	int ViewportY;
	int ViewportWidth;
	int ViewportHeight;
	float ViewportN;
	float ViewportF;
	LPDIRECT3DSURFACE9 RenderTarget;
	char ClsColorR;
	char ClsColorG;
	char ClsColorB;
	D3DXMATRIXA16 ProjMatrix;
};

struct MESH
{
	CDXUTMesh           Mesh;
	CDXUTMeshFrame      MeshFrame;	
	D3DMATERIAL9*       Materials;
	LPDIRECT3DTEXTURE9* Textures;
};

struct ENTITY
{
	float px;
	float py;
	float pz;
	float rx;
	float ry;
	float rz;
	float sx;
	float sy;
	float sz;
	int Parent;
	char Class;
	CAMERA CPTR;
	MESH   MPTR;
};

ENTITY Entity[100000];
int EntityCNT = 0;


int D3DWIDTH;
int D3DHEIGHT;



#define IDC_TOGGLEFULLSCREEN    1
#define IDC_TOGGLEREF           3
#define IDC_CHANGEDEVICE        4

bool    CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
bool    CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
void    CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
void    CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );
void    CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );
void    CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );
void    CALLBACK OnLostDevice( void* pUserContext );
void    CALLBACK OnDestroyDevice( void* pUserContext );

void    InitApp();
void    RenderText(double fTime);

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

#define BBDECL extern "C" _declspec(dllexport)
#define BBCALL _stdcall


BBDECL int BBCALL Graphics3D( int w, int h, int d, int m )
{
    // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

    
    DXUTSetCallbackDeviceCreated( OnCreateDevice );
    DXUTSetCallbackDeviceReset( OnResetDevice );
    DXUTSetCallbackDeviceLost( OnLostDevice );
    DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
    DXUTSetCallbackMsgProc( MsgProc );
    DXUTSetCallbackKeyboard( KeyboardProc );
    DXUTSetCallbackFrameRender( OnFrameRender );
    DXUTSetCallbackFrameMove( OnFrameMove );

    // Show the cursor and clip it when in full screen
    DXUTSetCursorSettings( true, true );

    InitApp();

	bool Windowed;

	switch (m)
	{
	case 1:
		Windowed = false;
	case 2:
		Windowed = true;
	default:
		Windowed = true;
	}
    // Initialize DXUT and create the desired Win32 window and Direct3D 
    // device for the application. Calling each of these functions is optional, but they
    // allow you to set several options which control the behavior of the framework.
    DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
    DXUTCreateWindow( L"Nexus 3D Engine" );
	
	DXUTDeviceSettings Settings;
	
	D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed = Windowed;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.BackBufferWidth = w;
	d3dpp.BackBufferHeight = h;

	Settings.AdapterFormat = D3DFMT_A8R8G8B8;
	Settings.AdapterOrdinal = D3DADAPTER_DEFAULT;
	Settings.BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE;
	Settings.DeviceType = D3DDEVTYPE_HAL;
	Settings.pp = d3dpp;

	DXUTCreateDeviceFromSettings( &Settings );
	
	Device = DXUTGetD3DDevice();
    
	D3DWIDTH = w;
	D3DHEIGHT = h;

    return DXUTGetExitCode();
}


//--------------------------------------------------------------------------------------
// Initialize the app 
//--------------------------------------------------------------------------------------
void InitApp()
{
    // Initialize dialogs
    g_SettingsDlg.Init( &g_DialogResourceManager );
    g_HUD.Init( &g_DialogResourceManager );

    g_HUD.SetCallback( OnGUIEvent ); int iY = 10; 
    g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 35, iY, 125, 22 );
    g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 35, iY += 24, 125, 22 );
    g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 35, iY += 24, 125, 22, VK_F2 );
}


//--------------------------------------------------------------------------------------
// Called during device initialization, this code checks the device for some 
// minimum set of capabilities, and rejects those that don't pass by returning false.
//--------------------------------------------------------------------------------------
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 
                                  D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )
{
    // Skip backbuffer formats that don't support alpha blending
    IDirect3D9* pD3D = DXUTGetD3DObject(); 
    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 
                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
        return false;

    return true;
}


//--------------------------------------------------------------------------------------
// This callback function is called immediately before a device is created to allow the 
// application to modify the device settings. The supplied pDeviceSettings parameter 
// contains the settings that the framework has selected for the new device, and the 
// application can make any desired changes directly to this structure.  Note however that 
// DXUT will not correct invalid device settings so care must be taken 
// to return valid device settings, otherwise IDirect3D9::CreateDevice() will fail.  
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )
{
    // If device doesn't support HW T&L or doesn't support 1.1 vertex shaders in HW 
    // then switch to SWVP.
    if( (pCaps->DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) == 0 ||
         pCaps->VertexShaderVersion < D3DVS_VERSION(1,1) )
    {
        pDeviceSettings->BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }

    // Debugging vertex shaders requires either REF or software vertex processing 
    // and debugging pixel shaders requires REF.
#ifdef DEBUG_VS
    if( pDeviceSettings->DeviceType != D3DDEVTYPE_REF )
    {
        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;
        pDeviceSettings->BehaviorFlags &= ~D3DCREATE_PUREDEVICE;
        pDeviceSettings->BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }
#endif
#ifdef DEBUG_PS
    pDeviceSettings->DeviceType = D3DDEVTYPE_REF;
#endif

    // For the first device created if its a REF device, optionally display a warning dialog box
    static bool s_bFirstTime = true;
    if( s_bFirstTime )
    {
        s_bFirstTime = false;
        if( pDeviceSettings->DeviceType == D3DDEVTYPE_REF )
            DXUTDisplaySwitchingToREFWarning();
    }

    return true;
}


//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has been 
// created, which will happen during application initialization and windowed/full screen 
// toggles. This is the best location to create D3DPOOL_MANAGED resources since these 
// resources need to be reloaded whenever the device is destroyed. Resources created  
// here should be released in the OnDestroyDevice callback. 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    HRESULT hr;


    V_RETURN( g_DialogResourceManager.OnCreateDevice( pd3dDevice ) );
    V_RETURN( g_SettingsDlg.OnCreateDevice( pd3dDevice ) );
    // Initialize the font
    V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, 
                         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, 
                         L"Verdana", &g_pFont ) );

    
    // Setup the camera's view parameters
    //g_Camera.SetViewQuat( D3DXQUATERNION(-4.275f, 0.3f, 0.0f, 0.7f) );


    return S_OK;
}


//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has been 
// reset, which will happen after a lost device scenario. This is the best location to 
// create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever 
// the device is lost. Resources created here should be released in the OnLostDevice 
// callback. 
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
{
    HRESULT hr;
	
    V_RETURN( g_DialogResourceManager.OnResetDevice() );
    V_RETURN( g_SettingsDlg.OnResetDevice() );

    if( g_pFont )
        V_RETURN( g_pFont->OnResetDevice() );
    
    // Create a sprite to help batch calls when drawing many lines of text
    V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );

    // Setup render states
    pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
    //pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_ );

    

    // Setup the camera's projection parameters
    float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
    
    g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
    g_HUD.SetSize( 170, 170 );
    
    return S_OK;
}


//--------------------------------------------------------------------------------------
// This callback function will be called once at the beginning of every frame. This is the
// best location for your application to handle updates to the scene, but is not 
// intended to contain actual rendering calls, which should instead be placed in the 
// OnFrameRender callback.  
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
  
  
}


//--------------------------------------------------------------------------------------
// This callback function will be called at the end of every frame to perform all the 
// rendering calls for the scene, and it will also be called if the window needs to be 
// repainted. After this function has returned, DXUT will call 
// IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
	HRESULT hr;
	D3DVIEWPORT9 View;
	D3DVIEWPORT9 OldView;
	D3DRECT Rect;
	D3DXMATRIXA16 Matrix;
	D3DXMATRIXA16 Matrix2;
    // If the settings dialog is being shown, then
    // render it instead of rendering the app's scene
    if( g_SettingsDlg.IsActive() )
    {
        g_SettingsDlg.OnRender( fElapsedTime );
        return;
    }
	Device->GetViewport(&OldView);
	Device->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1000.0f, 0 );
	for (int i=1; i<=EntityCNT; i++)
	{
		if (Entity[i].Class == 1)
		{
				
		View.X = Entity[i].CPTR.ViewportX;
		View.Y = Entity[i].CPTR.ViewportY;
		View.Width = Entity[i].CPTR.ViewportWidth;
		View.Height = Entity[i].CPTR.ViewportHeight;
		View.MinZ = Entity[i].CPTR.ViewportN;
		View.MaxZ = Entity[i].CPTR.ViewportF;
		
		Rect.x1 = Entity[i].CPTR.ViewportX;
		Rect.y1 = Entity[i].CPTR.ViewportY;
		Rect.x2 = Entity[i].CPTR.ViewportX + Entity[i].CPTR.ViewportWidth;
		Rect.y2 = Entity[i].CPTR.ViewportY + Entity[i].CPTR.ViewportHeight;
		
		
		//Device->SetRenderTarget(0,Entity[i].CPTR.RenderTarget);
		Device->SetViewport(&View);
		Device->Clear( 1, &Rect, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(Entity[i].CPTR.ClsColorR,Entity[i].CPTR.ClsColorG,Entity[i].CPTR.ClsColorB), 1000.0f, 0 );
		
		if( SUCCEEDED( pd3dDevice->BeginScene() ) )
			{
						D3DXMatrixScaling(&Matrix,Entity[i].sx,Entity[i].sy,Entity[i].sz);
					    D3DXMatrixTranslation(&Matrix2,-Entity[i].px,-Entity[i].py,-Entity[i].pz);
						D3DXMatrixMultiply(&Matrix,&Matrix,&Matrix2);						
						D3DXMatrixRotationYawPitchRoll(&Matrix2,-Entity[i].ry,-Entity[i].rx,-Entity[i].rz);
						D3DXMatrixMultiply(&Matrix,&Matrix,&Matrix2);
						
						Device->SetTransform( D3DTS_VIEW, &Matrix );
						Device->SetTransform( D3DTS_PROJECTION, &Entity[i].CPTR.ProjMatrix );
						
				for (int cnt=1; cnt<=EntityCNT; cnt++)
					{
						if (Entity[cnt].Class == 2)
						{
							D3DXMatrixScaling(&Matrix,Entity[cnt].sx,Entity[cnt].sy,Entity[cnt].sz);
					    	D3DXMatrixTranslation(&Matrix2,Entity[cnt].px,Entity[cnt].py,Entity[cnt].pz);
							D3DXMatrixMultiply(&Matrix,&Matrix,&Matrix2);						
							D3DXMatrixRotationYawPitchRoll(&Matrix2,Entity[cnt].ry,Entity[cnt].rx,Entity[cnt].rz);
							D3DXMatrixMultiply(&Matrix,&Matrix2,&Matrix);
						

							Device->SetTransform( D3DTS_WORLD, &Matrix );
							Entity[cnt].MPTR.Mesh.Render(Device);
						}
					}
				 Device->SetViewport(&OldView);
				 RenderText(fTime);
				  V( g_HUD.OnRender( fElapsedTime ) );
				
				  V( pd3dDevice->EndScene() );
			}
		
		}
	}
}


//--------------------------------------------------------------------------------------
// Render the help and statistics text. This function uses the ID3DXFont interface for 
// efficient text rendering.
//--------------------------------------------------------------------------------------
void RenderText(double fTime)
{
    // The helper object simply helps keep track of text position, and color
    // and then it calls pFont->DrawText( g_pSprite, strMsg, -1, &rc, DT_NOCLIP, g_clr );
    // If NULL is passed in as the sprite object, then it will work however the 
    // pFont->DrawText() will not be batched together.  Batching calls will improves performance.
    CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
	
    // Output statistics
    txtHelper.Begin();
    txtHelper.SetInsertionPos( 5, 5 );
    txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
    txtHelper.DrawTextLine( DXUTGetFrameStats(true) );
    txtHelper.DrawTextLine( DXUTGetDeviceStats() );

    txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
    txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
	txtHelper.DrawFormattedTextLine( L"fTime: %0.1f   Tris Rendered: %i Faces", fTime, Entity[3].MPTR.Mesh.m_dwNumFaces );
    
    // Draw help
    if( g_bShowHelp )
    {
        const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
        txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*6 );
        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );
        txtHelper.DrawTextLine( L"Controls (F1 to hide):" );

        txtHelper.SetInsertionPos( 40, pd3dsdBackBuffer->Height-15*5 );
        txtHelper.DrawTextLine( L"Rotate model: Left mouse button\n"
                                L"Rotate camera: Right mouse button\n"
                                L"Zoom camera: Mouse wheel scroll\n"
                                L"Hide help: F1" );                                      
		
    }
    else
    {
        txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
        txtHelper.DrawTextLine( L"Press F1 for help" );
    }

    txtHelper.End();
}


//--------------------------------------------------------------------------------------
// Before handling window messages, DXUT passes incoming windows 
// messages to the application through this callback function. If the application sets 
// *pbNoFurtherProcessing to TRUE, then DXUT will not process this message.
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext )
{
    // Always allow dialog resource manager calls to handle global messages
    // so GUI state is updated correctly
    *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing )
        return 0;

    if( g_SettingsDlg.IsActive() )
    {
        g_SettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );
        return 0;
    }

    // Give the dialogs a chance to handle the message first
    *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
    if( *pbNoFurtherProcessing )
        return 0;
    
    // Pass all remaining windows messages to camera so it can respond to user input
    

    return 0;
}


//--------------------------------------------------------------------------------------
// As a convenience, DXUT inspects the incoming windows messages for
// keystroke messages and decodes the message parameters to pass relevant keyboard
// messages to the application.  The framework does not remove the underlying keystroke 
// messages, which are still passed to the application's MsgProc callback.
//--------------------------------------------------------------------------------------
void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )
{
    if( bKeyDown )
    {
        switch( nChar )
        {
            case VK_F1: g_bShowHelp = !g_bShowHelp; break;
        }
    }
}


//--------------------------------------------------------------------------------------
// Handles the GUI events
//--------------------------------------------------------------------------------------
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )
{
    switch( nControlID )
    {
        case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
        case IDC_TOGGLEREF:        DXUTToggleREF(); break;
        case IDC_CHANGEDEVICE:     g_SettingsDlg.SetActive( !g_SettingsDlg.IsActive() ); break;
    }
}


//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has 
// entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
// in the OnResetDevice callback should be released here, which generally includes all 
// D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for 
// information about lost devices.
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice( void* pUserContext )
{
    g_DialogResourceManager.OnLostDevice();
    g_SettingsDlg.OnLostDevice();
    if( g_pFont )
        g_pFont->OnLostDevice();
    
    
    SAFE_RELEASE( g_pTextSprite );
	
}


//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has 
// been destroyed, which generally happens as a result of application termination or 
// windowed/full screen toggles. Resources created in the OnCreateDevice callback 
// should be released here, which generally includes all D3DPOOL_MANAGED resources. 
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice( void* pUserContext )
{
    g_DialogResourceManager.OnDestroyDevice();
    g_SettingsDlg.OnDestroyDevice();
    SAFE_RELEASE( g_pFont );
    for (int i=0;i<=EntityCNT;i++)
	{
		if (Entity[i].Class == 2)
		{
			Entity[i].MPTR.Mesh.Destroy();
			//Entity[i].MPTR.Mesh->Release();
		}
	}
}



BBDECL int BBCALL RenderWorld()
{
	if (SUCCEEDED(DXUTIsActive()))
	{
	DXUTRender3DEnvironment();
	return 1;
	}
	return 0;
}

BBDECL int BBCALL CameraClsColor( int PTR, int r, int g, int b )
{
	 
	Entity[PTR].CPTR.ClsColorR = r;
	Entity[PTR].CPTR.ClsColorG = g;
	Entity[PTR].CPTR.ClsColorB = b;
		
	return 1;
}
BBDECL int BBCALL CameraViewport( int PTR, int x, int y, int w, int h )
{
	 
			Entity[PTR].CPTR.ViewportX = x;
			Entity[PTR].CPTR.ViewportY = y;
			Entity[PTR].CPTR.ViewportWidth = w;
			Entity[PTR].CPTR.ViewportHeight = h;
				
	return 1;
}

BBDECL int BBCALL CreateCamera()
{
	EntityCNT = EntityCNT + 1;
	Entity[EntityCNT].Class = 1;
	Entity[EntityCNT].CPTR.ClsColorR = 0; 
	Entity[EntityCNT].CPTR.ClsColorG = 0;
	Entity[EntityCNT].CPTR.ClsColorB = 0;
	Entity[EntityCNT].CPTR.RenderTarget = BackBuffer;
	Entity[EntityCNT].CPTR.ViewportX = 0;
	Entity[EntityCNT].CPTR.ViewportY = 0;
	Entity[EntityCNT].CPTR.ViewportWidth = D3DWIDTH;
	Entity[EntityCNT].CPTR.ViewportHeight = D3DHEIGHT;
	Entity[EntityCNT].CPTR.ViewportN = 0.0f;
	Entity[EntityCNT].CPTR.ViewportF = 1.0f;
	D3DXMatrixPerspectiveFovLH( &Entity[EntityCNT].CPTR.ProjMatrix, D3DX_PI/2.5f, 1.5f, 1.0f, 100.0f );
	Entity[EntityCNT].sx = 1.0f;
	Entity[EntityCNT].sy = 1.0f;
	Entity[EntityCNT].sz = 1.0f;
	return EntityCNT;
}


BBDECL int BBCALL LoadMesh(char* fName)
{
	//LPD3DXBUFFER D3DXMtrlBuffer;

	size_t origsize = strlen(fName) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, fName, _TRUNCATE);
    
	EntityCNT = EntityCNT + 1;
	Entity[EntityCNT].sx = 1.0f;
	Entity[EntityCNT].sy = 1.0f;
	Entity[EntityCNT].sz = 1.0f;
	
	
	if ( FAILED(Entity[EntityCNT].MPTR.Mesh.Create(Device,wcstring)))
	{
		EntityCNT = EntityCNT - 1;
		return 0;
	}
	//
	    
    Entity[EntityCNT].MPTR.Mesh.UseMeshMaterials(true);
    //D3DXMtrlBuffer->Release();
	Entity[EntityCNT].Class = 2;
    return EntityCNT;
}



BBDECL char* BBCALL EntityClass(int PTR)
{
	switch (Entity[PTR].Class)
	{
	case 1:
		return "Camera";
	case 2:
		return "Mesh";
	case 3:
		return "Light";
	default:
		return "";
	}
	return "";
}
BBDECL void BBCALL PositionEntity(int PTR, float x, float y, float z)
{
	Entity[PTR].px = x;
	Entity[PTR].py = y;
	Entity[PTR].pz = z;
}
BBDECL int BBCALL ScaleEntity(int PTR, float x, float y, float z)
{
	Entity[PTR].sx = x;
	Entity[PTR].sy = y;
	Entity[PTR].sz = z;
	return 1;
}
BBDECL int BBCALL RotateEntity(int PTR, float x, float y, float z)
{
	Entity[PTR].rx = x * (D3DX_PI / 180.0f);
	Entity[PTR].ry = y * (D3DX_PI / 180.0f);
	Entity[PTR].rz = z * (D3DX_PI / 180.0f);
	return 1;
}
BBDECL int BBCALL PointEntity(int PTR, int ENT)
{
	D3DXMATRIXA16 Mat;
	D3DXVECTOR3 vEyePt( Entity[PTR].px, Entity[PTR].py, Entity[PTR].pz );
    D3DXVECTOR3 vLookatPt( Entity[ENT].px, Entity[ENT].py, Entity[ENT].pz );
    D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
	D3DXVECTOR3 Pos;
	D3DXQUATERNION Rot;
	D3DXVECTOR3 Scale;
	D3DXMatrixLookAtLH( &Mat, &vEyePt, &vLookatPt, &vUpVec );
	D3DXMatrixDecompose(&Scale,&Rot,&Pos,&Mat);
	Entity[PTR].rx = Rot.x;
	Entity[PTR].ry = Rot.y;
	return 1;
}

BBDECL float BBCALL EntityPitch(int PTR)
{return D3DXToDegree(Entity[PTR].rx);}

BBDECL float BBCALL EntityYaw(int PTR)
{return D3DXToDegree(Entity[PTR].ry);}

BBDECL float BBCALL EntityRoll(int PTR)
{return D3DXToDegree(Entity[PTR].rz);}

BBDECL float BBCALL EntityX(int PTR)
{return Entity[PTR].px;}

BBDECL float BBCALL EntityY(int PTR)
{return Entity[PTR].py;}

BBDECL float BBCALL EntityZ(int PTR)
{return Entity[PTR].pz;}