New B3D-like Direct3D9/10 Engine

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

Hi everybody! I am making a new engine for B+, B3D and propertly BMax. It is based on the new Direct3D 10 Renderer using Win Vista, and can also do Direct3D 9. All new features from DX10 will be available in one or another form.
All the old B3D commands are used here.
LoadMesh, PositionEntity, CameraViewport, all of 'em.
Any comments? :-)

Link to screenshot:
http://gallery.artodata.dk/data/user/gallery/images/470/470dd079-178d-41da-9571-472293547ca1.jpg?opdateret=18-10-2006+00%3a26%3a00

That's in BlitzPlus? (I can see the window title)
Seems like all the blitz languages do everthing now.

where can we download :)

Will it require vista?

The fact that it seems to use standard Blitz3D commands is a massive plus point.

Hurry up and finish it! I think you'll have plenty of customers if it's good. :)

I will be most excited when it is released.

How about an eraly beta or demo to show us

April Fools day - in October ?

Yeah, I am waiting for this as well

So basically this is a rival to B3D but using the same set of commands. I wonder now will this ever be finished? I doubt it.

So basically this is a rival to B3D but using the same set of commands. I wonder now will this ever be finished? I doubt it.

I don't think 'rival' is the word. Surely you have to buy Blitz3D to use this.

We will see how far it goes. It would be nice to have a rendering engine alternative but so far, none ever got finished because there are 2 things that normally break them:

Collision
Movie Support

We will see which one will end this project if any does.
Rendering is the easy part of wrapping the Blitz 3D commandset.

Ah and let's have dynamic collision support please.

You don't need Blitz3D.. You just need BlitzPlus, or C++.. Lib's for both B+ and C++ will be released.. Maybe also for BlitzMAX.. ;) Development restarted because of an wierd bug that closed the app. after 5 min run.. Now the engine is based on the DXUT tool included with the latest DX9 SDK (GUI, automatic resolution setup etc.), but i'm fully working on the engine.. ;)

... will it require vista?
- No, DirectX 10 wil be released for XP in a few months
... Collision, and Movie support
- Collisions will be sphere-to-polygon and sphere-to-sphere.
Maybe sphere-to-box, not known yet..
- I think there will be DirectShow movie-support. If i'm right, i think that you can render the movie to a d3d-surface.

Development restarted because of an wierd bug that closed the app. after 5 min run


That's odd. Wouldn't a bug like that be relatively easy to spot if you coded everything?

"Development restarted because of an wierd bug that closed the app. after 5 min run"

- AKA -

"I'm never going to finish this project!"

Tell us about this when it's done, not when it's a burning idea waiting to find an excuse to fail.

..hihiihiihi...

A little bit too early for april the 1st if you ask me.

It's a little hard to spot such bugs, i only got four weeks of C++ experience.. But i'm still working on it.. Multiple cameras (viewports) works, meshes can be loaded, positioned, rotated and scaled.

..you have got 4 weeks of C++ experiance and going to create game engine??

- No, DirectX 10 wil be released for XP in a few months


where did you hear that? Microsoft have stated there will be no direct X 10 for XP.


you have got 4 weeks of C++ experiance and going to create game engine??



What alien said!!!

- DirectX 10 , i heard it from a friend..

- Yes about a month.. I studied the DirectX SDK, and started programming.. I don't find C++ so hard to learn, when you already know MUCH Blitz- or Visual Basic.. ;)
I'm only fifteen so maybe i am easier learning.. :D

Not to burst Qimmers bubble, but a couple things.

1. There will be no Dx10 for XP. Your friend is clueless. Game developers will have to write two rendering pipelines for a while to come Dx9 and Dx10. The DXUT Lib takes care of alot of that for you in regards to setup Creating a Dx9 Context or Dx10 context based upon enviorment. Vista supports both for these reason. Dx10 is not backwards compatibile. It is entirely different architecture then Dx9. Dx9 supports fixed piplines Dx10 does not. Dx10 requires Unified Shaders Dx9 does not. There are no Dx10 cards currently available. End of the Month most likely.

2. The SDK DxUT Lib that you are wrapping, is a good starting point, however it wont work on anything but WinNT Kernal OS. Not that I think supporting Win9x is important but figured you might want to know that.

3. An engine requires more than just wrapping DXUT. Its just the basics, so you need to understand your 3d Math inside and out. How is your trig?


Now for advice, take your time, and dont even begin to estimate how long its going to take. You wrapped the libary and got some basic rendering going. Dont take offense thats not a big deal. And there are many talented programmers here that can do that. As for learning C++. There is good and bad programming in C++ whats good for VB or Blitz is more than likely very bad for C++. I have been programming various languages professionaly for over 25 years and can program in C++ but dont even remotely consider myself great at it. I know enough to get by.

Make sure you really learn the language and understand. This is probably the best book.

http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

Good luck on your start in programming, many of us were you a long time ago.

Doug Stastny

<i> If D3D9 is supported by Win9x, DXUT is too! DXUT is just a set of code, that makes it more stable, and easier to code the generally things (such like setting up the device).
I've also got good experiences in 3d maths like vectors and matrices. The entity system is almost finished, you know, children, parents, and that stuff..
But you're right with DX10.. But then i'll just split the engine up in two DLL's.. One for DX9 rendering, and one for DX10 rendering.. And for those who can use the engine in C++, there will also be a x64-build of the engine.
Some interest of some C++ code? :)

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;}



Swear to god your sig said you were 14 like a day ago. Happy birthday. Here's your gift: It's a clue - what you are setting out to do is a waste of time. Do something more productive.

I'll release an alpha demo of the engine soon as i finish the entity system, camera system, and lightening system.. ;)

Qimmer, read the Doc on DXUT you are wrong.
It works on Unicode OS only. To support unicode on Win9x you must install seperate DLLs for Unicode support. So just becuase DXUT works with DX9 has nothing to do with OS. As you put it it is a piece of code... but code has dependencies, you need to be sure of them before you just start coding blindly.

Your code is not C++ its C. Thats what Extern "C" does.

Your entity math will fail with from Gimbal Lock. Google it you see what it is.

The big array of entities is kinda inefficent(I am being polite). You need to implement linked list or other more complex structure to deal with entities. Look at templates for better container management.

Keep learning... But you have a way to go. You just wrapped the SDK example in simple "C" DLL.

Doug Stastny

Collisions will be sphere-to-polygon and sphere-to-sphere

Linepick or a simple intersection check between two points in space and an entity is the be all and end all of collision. I use nothing else, never have, and never will.

Anyway I applaud the effort, you show great ambition and some talent. What you dont have is a well rounded understanding of all things code, and this will ultimately cause your project to have a few innefficiencies or issues as it nears completion.

However, keep at it. Fail this time, or succeed poorly, whichever doesnt matter. The fact is doing this must be teaching you a hell of a lot, and once you've done something once doing it again becomes a whole lot easier. Within a few attempts you'll be suceeding well.

Your crash bug was probably a memory leak, a resource no longer used not being freed. Take some time to look into garbage collection, and do be sure to learn linked lists as arrays are very much too BASIC for this kind of work.

First, it doesn't matter if the engine can't run under Win 9x. How many uses this system anymore? Games like NFS Most Wanted and such also only runs under NT Kernel.. And that bug was because i had to use _stdcall instead of _cdecl.

Ignore them Qimmer, honestly! Go for it bro, prove them wrong!

@Liberator get back in your cage!

Budman has some good points, worth taking into consideration.

I completely agree with Banshee.

For best performance, cam someone help me with a good entity system? I just need the code to handle the entities (like 'new Entity[1]; , PositionEntity, Parent/Child system) you know. Then i'll take care of the rest.. I don't have so good math skills yet.. And i don't really know how to handle the entity-variables.

why not checkout the blitz system that was coded for bmax that might help you with entity stuff.

You're forgetting 'break' in your switch/case so 'Windowed' always gets set to true, and 'case 2' does the exact thing 'default' does; you could probably do it with 'if' instead but this is what the switch/case should look like:

	switch (m)
	{
	case 1:
		Windowed = false;
		break;
	default:
		Windowed = true;
	}


@Qimmer FYI, you might want to use the codebox rather than code tags for large amount of code.

..I like this kid..

why not checkout the blitz system that was coded for bmax that might help you with entity stuff.

Do you mean MiniB3D?

i fixed the gimbal lock! when using minib3d's matrix system, year the gimbal lock occurs when recieving the pitch yaw roll in the global coords.. but why not just add all the parents rotation angles to the local angle, then you got the global angle in degrees?

I say hats off! I wish I was 14 again, or 18 or so, when every day had 72 hours. Good luck Qimmer, the world's out there to be conquered.

Yeah, ignore the nay-sayers and just do it.

Totally agreed!
Qimmer, most of those guys are old and delusioned, so listen to what their experience has to say, but don't let them bring you down!

What you're doing is awesome. So, the engine is not perfect now? Big deal! You're 15, have all the time in the world!

Go ahead, rock on, take over the world!
Leo.

..son..do it,but dont fly to high becouse you can fall deep..now go and get it tiger :)

When he'll be over with it, Direct X 12 will be out! And Blitz3D will already be DX9!!!

Blitz3D will already be DX9!!!


I highly doubt that ...

Without hope, you have death.

"A hopeless situation"

I've learned a lot since that screenshot i made for about 8 months ago .. I've almost only been developing C/C++ since, and now i know how to do:

- The entity-system, gimbal lock, parent/children etc.
- Shadowmapping
- Hardware-skinning for boned animations and anim.-blending
- a lot about HLSL shaders

... and more to come ..

I've started from scratch with my Nexus 3D Engine ...

..Im not going to spoil your enthusiasm, but am I asking much if I say I would like to see some screenshots??

.. as i said: i have learned a lot ...

And as the DirectX 10 buildt-in instancing functions, it is going to be easy to make hardware instancing, just using CopyEntity.

I know its nonsless, but as you asked for a screenshot, you can see one here: http://www.box.net/shared/cxi7pk1aif

I coded in 2 days now, but the reason why it doesnt look that much, is because the whole matrix, entity child/parent system etc. is coded now .. I just need to implement some drawing methods, then i'll post a screenshot again, and maybe a bit code as a proof on how long i am in progress.

That looks like a blank screen to me.

Some of you ment that it would be impossible for me to develop a DX9/10 engine in an age of 15 right?
I've only developed C++ in a year now, and look at this:

http://blitzbasic.com/logs/userlog.php?user=8985&log=1544

Some of you ment that it would be impossible for me to develop a DX9


No, but we have now (i think) 8 different dx engines on this board, what we want is somethink to download (buy?) and use. All the rest (worklogs,threads etc etc)....who cares?

bye

Edit: here is number9 : http://www.blitzbasic.com/Community/posts.php?topic=75451 ;) NEW-HOT-&-FRESH

Just to say, i have been working on nexus for about a half year now :S

that looks really good Quimmer, are you gonna release a demo soon?

Here, i made a demo yesterday:

http://blitzbasic.com/logs/userlog.php?user=8985&log=1544

Very interesting. Will download the demo as soon as i get home.

Doesn't run, PhysXLoader.dll not found

Yep same problem here, needs PhysXLoader.dll

So I went on a hunt and downloaded the dll from here:
http://www.dll-files.com/dllindex/dll-files.shtml?physxloader

Now it cant for some reason open the Zombie.jpg texture...

the physx drivers are on the ageia website

my graphics card cant handle shaders so it said: 'cant create directx device'

could you release a version with fallbacks?
e.g. dont display shaders if the card cant handle it

"Cannot open Zombie.jpg"

"Cannot open Zombie.jpg"

All files are in the same directory as exe.

"Cannot open Zombie.jpg"

I'll check for that Zombie.jpg problem.

You need to install the latest PhysX drivers, because the engine implements PhysX.

You need a Pixel Shader 2.0 compliant graphics card, as the engine is based on shaders only, no Fixed Function. Thats so the engine is Direct3D 10.

Can you please take a screenshot of the Zombie.jpg error, and send it to twicfall@...? I would be glad to solve that problem.

It just says that windows message ("Cannot open Zombie.jpg" ) when you try to run the exe.

Worked ok here

your demo does not only require the ageia drivers, but i had to move those dlls into your program directory.

[b]and it still says "texture zombie.jpg not found"

Its strange, because that Zombie.jpg error does only happen on certain systems. And the problem seems to be in the D3DXLoadTexture() command in Direct3D.

I hope you get this working. It looks like you have worked very hard on it. I applaud your efforts thus far :o)

Nice water... keep your excellent job.

works ok here (geforce8). looking the other posts up, i would say it doesnt work on amd/ati cards...just a guess...

dont see anything special dx9 here though...its not even compiled with blitz3d, so i dont understand, why its in the _blitz_ showcase...

dont get me wrong, i appreciate your work. but...ive yet to see something, that gets me wanting to use your engine! small techdemos are really something fundamentally different then a fully fledged 3D engine...thats why we're seeing one "dx9 engine" after another, but havent seen even ONE finished till today ;)

but...im eager to get proven wrong! :)

Not working here...

P4, 2.4Gigz, 1Gig RAM, nVidia 7600GT, 256MB VRAM, WinXP Pro, SP2

It worked here, but as Ojay mentioned, nothing special. I'd like to see more on this though, so please provide more demos with stuff you have besides this, which could have been done with just Blitz3d.

p4 3.6ghz, 1gb ram, ati radeon x1650, xp