lets do this properly.

git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1144 993157c7-ee19-0410-b2c4-bb4e9862e678
This commit is contained in:
chrisf
2007-07-10 02:24:10 +00:00
parent 3338422abc
commit 206df3514e
19 changed files with 1657 additions and 0 deletions

18
BluntDx/AssemblyInfo.cpp Normal file
View File

@@ -0,0 +1,18 @@
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
[assembly:AssemblyTitleAttribute("BluntDx")];
[assembly:AssemblyDescriptionAttribute("BluntDirectX Lightweight MDX Replacement")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("C Forbes & Associates")];
[assembly:AssemblyProductAttribute("BluntDx")];
[assembly:AssemblyCopyrightAttribute("Copyright (c) C Forbes & Associates 2006")];
[assembly:AssemblyTrademarkAttribute("")];
[assembly:AssemblyCultureAttribute("")];
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(false)];
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];

270
BluntDx/BluntDx.vcproj Normal file
View File

@@ -0,0 +1,270 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="BluntDx"
ProjectGUID="{4EA97564-C929-4ABE-AC5D-A9D11EDE08E1}"
RootNamespace="BluntDx"
Keyword="ManagedCProj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(NoInherit)"
LinkIncremental="2"
GenerateDebugInformation="true"
AssemblyDebug="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine=""
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="1"
ManagedExtensions="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="$(NoInherit)"
LinkIncremental="1"
GenerateDebugInformation="true"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
CommandLine="copy &quot;$(TargetPath)&quot; &quot;$(SolutionDir)bin\&quot;"
/>
</Configuration>
</Configurations>
<References>
<AssemblyReference
RelativePath="System.dll"
AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
/>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\AssemblyInfo.cpp"
>
</File>
<File
RelativePath=".\Direct3D.cpp"
>
</File>
<File
RelativePath=".\DirectInput.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\Utilities.h"
>
</File>
</Filter>
<Filter
Name="Direct3D"
>
<File
RelativePath=".\Effect.h"
>
</File>
<File
RelativePath=".\Enumerations.h"
>
</File>
<File
RelativePath=".\FontHelper.h"
>
</File>
<File
RelativePath=".\GraphicsDevice.h"
>
</File>
<File
RelativePath=".\ImageInformation.h"
>
</File>
<File
RelativePath=".\Mesh.h"
>
</File>
<File
RelativePath=".\SpriteHelper.h"
>
</File>
<File
RelativePath=".\Texture.h"
>
</File>
<File
RelativePath=".\VertexBuffer.h"
>
</File>
</Filter>
<Filter
Name="DirectInput"
>
<File
RelativePath=".\InputDevice.h"
>
</File>
<File
RelativePath=".\InputManager.h"
>
</File>
<File
RelativePath=".\JoystickState.h"
>
</File>
<File
RelativePath=".\KeyboardState.h"
>
</File>
<File
RelativePath=".\MouseState.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

39
BluntDx/Direct3D.cpp Normal file
View File

@@ -0,0 +1,39 @@
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma unmanaged
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma managed
#include <vcclr.h>
#pragma once
#using "System.Drawing.dll"
#using "System.Windows.Forms.dll"
using namespace System;
using namespace System::Windows::Forms;
using namespace System::IO;
using namespace System::Drawing;
#include "Utilities.h"
#include "Enumerations.h"
#include "GraphicsDevice.h"
#include "ImageInformation.h"
#include "Texture.h"
#include "SpriteHelper.h"
#include "FontHelper.h"
#include "Mesh.h"
#include "Effect.h"
#include "VertexBuffer.h"

37
BluntDx/DirectInput.cpp Normal file
View File

@@ -0,0 +1,37 @@
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma unmanaged
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0500
#define INITGUID
#define DIRECTINPUT_VERSION 0x0800
#include <windows.h>
#include <dinput.h>
#pragma managed
#include <vcclr.h>
#pragma once
#using "System.Drawing.dll"
#using "System.Windows.Forms.dll"
using namespace System;
using namespace System::Windows::Forms;
using namespace System::IO;
using namespace System::Drawing;
#include "Utilities.h"
#include "InputManager.h"
#include "KeyboardState.h"
#include "MouseState.h"
#include "JoystickState.h"
#include "InputDevice.h"

165
BluntDx/Effect.h Normal file
View File

@@ -0,0 +1,165 @@
#pragma once
using namespace System::Collections::Generic;
namespace BluntDirectX { namespace Direct3D
{
public enum class ShaderQuality
{
Low,
Medium,
High,
};
public ref class Effect
{
private:
static ID3DXEffectPool* effectPool;
static Effect()
{
ID3DXEffectPool* e;
D3DXCreateEffectPool( &e );
effectPool = e;
}
ShaderQuality shaderQuality;
internal:
ID3DXEffect* effect;
public:
Effect(GraphicsDevice^ device, Stream^ data)
{
ID3DXEffect* e;
ID3DXBuffer* compilationErrors;
HRESULT hr;
data->Position = 0;
array<unsigned char>^ bytes = gcnew array<unsigned char>((int)data->Length);
data->Read( bytes, 0, (int)data->Length );
pin_ptr<unsigned char> pdata = &bytes[0];
if (FAILED( hr = D3DXCreateEffect( device->device, pdata, (UINT)data->Length, NULL, NULL,
D3DXSHADER_PACKMATRIX_COLUMNMAJOR | D3DXSHADER_USE_LEGACY_D3DX9_31_DLL, effectPool, &e, &compilationErrors ) ))
{
String^ errors = gcnew String((char*)compilationErrors->GetBufferPointer());
compilationErrors->Release();
throw gcnew InvalidOperationException( String::Format(
"Failed compiling shader; HRESULT={0}, Errors:\n{1}",
hr, errors ));
}
effect = e;
Quality = ShaderQuality::High;
}
IntPtr GetHandle( String^ symbol )
{
array<unsigned char>^ chars = System::Text::Encoding::ASCII->GetBytes(symbol);
pin_ptr<const unsigned char> p = &chars[0];
IntPtr result = IntPtr((void*)effect->GetParameterByName(NULL, (char*)p));
return result;
}
~Effect()
{
safe_release( effect );
}
property ShaderQuality Quality
{
ShaderQuality get() { return shaderQuality; }
void set( ShaderQuality s )
{
if (shaderQuality == s)
return;
shaderQuality = s;
switch(s)
{
case ShaderQuality::High:
if (SUCCEEDED(effect->SetTechnique( "high_quality" )))
break;
case ShaderQuality::Medium:
if (SUCCEEDED(effect->SetTechnique( "med_quality" )))
break;
case ShaderQuality::Low:
if (SUCCEEDED(effect->SetTechnique( "low_quality" )))
break;
default:
throw gcnew Exception( "Invalid shader quality" );
}
}
};
void Commit()
{
effect->CommitChanges();
}
int Begin()
{
unsigned int passes;
effect->Begin( &passes, D3DXFX_DONOTSAVESTATE | D3DXFX_DONOTSAVESHADERSTATE );
return passes;
}
void End()
{
effect->End();
}
void BeginPass(int pass)
{
effect->BeginPass( pass );
}
void EndPass()
{
effect->EndPass();
}
generic< typename T> where T : value class
void SetValue( IntPtr handle, T value )
{
pin_ptr<T> pvalue = &value;
effect->SetValue( (D3DXHANDLE)handle.ToPointer(), pvalue, sizeof(T) );
}
void SetTexture( IntPtr handle, Texture^ texture )
{
effect->SetTexture( (D3DXHANDLE)handle.ToPointer(), texture->texture );
}
property array<KeyValuePair<IntPtr, String^>>^ ShaderResources
{
array<KeyValuePair<IntPtr, String^>>^ get()
{
List<KeyValuePair<IntPtr, String^>>^ resources = gcnew List<KeyValuePair<IntPtr, String^>>();
int id = 0;
D3DXHANDLE parameter;
while( parameter = effect->GetParameter( NULL, id++ ) )
{
D3DXHANDLE annotation;
if (!(annotation = effect->GetAnnotationByName( parameter, "src" )))
continue;
char* value;
HRESULT hr;
if (FAILED(hr = effect->GetString( annotation, (LPCSTR*)&value )))
ThrowHelper::Hr(hr);
resources->Add( KeyValuePair<IntPtr, String^>( IntPtr( (void*)parameter ), gcnew String(value) ) );
}
return resources->ToArray();
}
}
};
}}

27
BluntDx/Enumerations.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
namespace BluntDirectX { namespace Direct3D
{
[Flags]
public enum class Surfaces
{
None = 0,
Color = D3DCLEAR_TARGET,
Depth = D3DCLEAR_ZBUFFER,
};
[Flags]
public enum class VertexFormat
{
None = 0,
Position = D3DFVF_XYZ,
Normal = D3DFVF_NORMAL,
Texture = D3DFVF_TEX1,
};
public enum class PrimitiveType
{
PointList = D3DPT_POINTLIST,
TriangleList = D3DPT_TRIANGLELIST,
};
}}

56
BluntDx/FontHelper.h Normal file
View File

@@ -0,0 +1,56 @@
#pragma once
namespace BluntDirectX { namespace Direct3D
{
public ref class FontHelper
{
private:
static int MakeLogicalFontHeight( int emSize )
{
int result;
HDC hdc = GetDC(NULL);
result = -MulDiv( emSize, GetDeviceCaps( hdc, LOGPIXELSY ), 72 );
ReleaseDC( NULL, hdc );
return result;
}
internal:
ID3DXFont* font;
public:
FontHelper( GraphicsDevice^ device, String^ face, int emSize, bool bold )
{
HRESULT hr;
ID3DXFont* f;
pin_ptr<const wchar_t> uface = PtrToStringChars(face);
int height = MakeLogicalFontHeight( emSize );
if (FAILED(
hr = D3DXCreateFont( device->device, height, 0, bold ? FW_BOLD : FW_NORMAL, 1, false,
DEFAULT_CHARSET, OUT_STRING_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
uface, &f)))
ThrowHelper::Hr(hr);
font = f;
}
void Draw( SpriteHelper^ sprite, String^ text, int x, int y, int color )
{
pin_ptr<const wchar_t> utext = PtrToStringChars(text);
RECT r = {x, y, x+1, y+1};
font->DrawText( sprite->sprite, utext, -1, &r, DT_LEFT | DT_NOCLIP, color );
}
Size MeasureText( SpriteHelper^ sprite, String^ text )
{
pin_ptr<const wchar_t> utext = PtrToStringChars(text);
RECT r = {0,0,1,1};
int height = font->DrawText( sprite->sprite, utext, -1, &r, DT_LEFT | DT_CALCRECT, 0 );
return Size( r.right - r.left, height );
}
};
}}

168
BluntDx/GraphicsDevice.h Normal file
View File

@@ -0,0 +1,168 @@
#pragma once
namespace BluntDirectX { namespace Direct3D
{
public ref class GraphicsDevice
{
private:
GraphicsDevice( IDirect3DDevice9* device, bool hasHardwareVp ) : device( device ), hardwareVp( hasHardwareVp )
{
IDirect3DSurface9* s;
device->GetRenderTarget(0, &s);
defaultSurface = s;
}
bool hardwareVp;
internal:
IDirect3DDevice9* device;
IDirect3DSurface9* defaultSurface;
void SetRenderTarget( IDirect3DSurface9* surface )
{
if (surface == nullptr)
surface = defaultSurface;
device->SetRenderTarget( 0, surface );
}
public:
void BindDefaultRenderTarget()
{
SetRenderTarget( nullptr );
}
void BindSurface( IntPtr p )
{
SetRenderTarget( (IDirect3DSurface9*) p.ToPointer() );
}
IntPtr GetDefaultSurface()
{
return IntPtr(defaultSurface);
}
void Begin()
{
device->BeginScene();
}
void End()
{
device->EndScene();
}
~GraphicsDevice()
{
safe_release( device );
}
void Clear( int color )
{
device->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, (D3DCOLOR)color, 1.0f, 0 );
}
void Clear( int color, Surfaces surfaces )
{
device->Clear( 0, NULL, (DWORD)surfaces, (D3DCOLOR)color, 1.0f, 0 );
}
void Present()
{
device->Present(NULL,NULL,NULL,NULL);
}
property bool HasHardwareVP
{
bool get() { return hardwareVp; }
}
static GraphicsDevice^ CreateRenderless()
{
IDirect3D9* d3d = Direct3DCreate9( D3D_SDK_VERSION );
D3DPRESENT_PARAMETERS pp;
memset( &pp, 0, sizeof(pp) );
pp.BackBufferCount = 1;
pp.BackBufferFormat = D3DFMT_UNKNOWN;
pp.BackBufferWidth = pp.BackBufferHeight = 1;
pp.SwapEffect = D3DSWAPEFFECT_COPY;
pp.Windowed = true;
IDirect3DDevice9* dev;
HRESULT hr;
if (FAILED(hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, GetConsoleWindow(),
D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &dev)))
ThrowHelper::Hr(hr);
return gcnew GraphicsDevice( dev, true );
}
static GraphicsDevice^ Create(Control^ host, int width, int height, bool windowed, bool vsync)
{
IDirect3D9* d3d = Direct3DCreate9( D3D_SDK_VERSION );
D3DPRESENT_PARAMETERS pp;
memset( &pp, 0, sizeof(pp) );
pp.BackBufferCount = vsync ? 1 : 2;
pp.BackBufferWidth = width;
pp.BackBufferHeight = height;
pp.BackBufferFormat = D3DFMT_X8R8G8B8;
pp.AutoDepthStencilFormat = D3DFMT_D24X8;
pp.EnableAutoDepthStencil = true;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.Windowed = windowed;
pp.PresentationInterval = (vsync && !windowed) ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
DWORD flags[] = {
D3DCREATE_PUREDEVICE | D3DCREATE_HARDWARE_VERTEXPROCESSING,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
D3DCREATE_MIXED_VERTEXPROCESSING,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
0
};
DWORD* pf = &flags[0];
while(*pf)
{
IDirect3DDevice9* pd;
HRESULT hr;
bool configHasHardwareVp = 0 != (*pf & D3DCREATE_HARDWARE_VERTEXPROCESSING);
if (SUCCEEDED( hr = d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, (HWND)host->Handle.ToInt32(),
*pf, &pp, &pd)))
return gcnew GraphicsDevice( pd, configHasHardwareVp );
++pf;
}
throw gcnew ApplicationException("D3D not available.");
}
void EnableScissor( int left, int top, int width, int height )
{
RECT r = { left, top, width, height };
device->SetScissorRect( &r );
device->SetRenderState( D3DRS_SCISSORTESTENABLE, true );
}
void DisableScissor()
{
device->SetRenderState( D3DRS_SCISSORTESTENABLE, false );
}
void DrawPrimitives(PrimitiveType primtype, int count)
{
device->DrawPrimitive( (D3DPRIMITIVETYPE)primtype, 0, count );
}
void DrawIndexedPrimitives(PrimitiveType primtype, int vertexPoolSize, int numPrimitives)
{
device->DrawIndexedPrimitive( (D3DPRIMITIVETYPE)primtype, 0, 0, vertexPoolSize, 0, numPrimitives );
}
};
}}

View File

@@ -0,0 +1,36 @@
#pragma once
namespace BluntDirectX { namespace Direct3D
{
public value class ImageInformation
{
private:
ImageInformation( int width, int height, int depth, bool isCube )
: Width( width ), Height( height ), Depth( depth ), IsCube( isCube ) {}
public:
int Width;
int Height;
int Depth;
bool IsCube;
static ImageInformation Create( Stream^ stream )
{
D3DXIMAGE_INFO info;
stream->Position = 0;
array<unsigned char>^ data = gcnew array<unsigned char>( (int)stream->Length );
stream->Read( data, 0, data->Length );
HRESULT hr;
pin_ptr<unsigned char> p = &data[0];
if (FAILED( hr = D3DXGetImageInfoFromFileInMemory( p, data->Length, &info )))
throw gcnew InvalidOperationException( "image information load failed" );
return ImageInformation( info.Width, info.Height, info.Depth,
info.ResourceType == D3DRTYPE_CUBETEXTURE );
}
};
}}

153
BluntDx/InputDevice.h Normal file
View File

@@ -0,0 +1,153 @@
#pragma once
namespace BluntDirectX { namespace DirectInput
{
[Flags]
public enum class CooperativeLevel
{
OnlyWhenFocused = 0x1,
Exclusive = 0x2,
DisableWindowsKey = 0x4,
};
public enum class DeviceType
{
Keyboard,
Mouse,
Joystick,
};
public ref class DiInputDevice
{
private:
DiInputDevice( IDirectInputDevice8* device )
: device(device), devtype( DeviceType::Joystick ) {}
internal:
IDirectInputDevice8* device;
DeviceType devtype;
public:
static property Guid SystemKeyboard
{
Guid get()
{
return *(Guid*)&GUID_SysKeyboard;
}
}
static property Guid SystemMouse
{
Guid get()
{
return *(Guid*)&GUID_SysMouse;
}
}
DiInputDevice( InputManager^ manager, Guid guid, DeviceType devtype ) : devtype( devtype )
{
HRESULT hr;
IDirectInputDevice8* _device;
GUID* p = (GUID*)&guid;
if (FAILED( hr = manager->di->CreateDevice( *p, &_device, NULL )))
ThrowHelper::Hr(hr);
device = _device;
}
void SetCooperativeLevel( Control^ host, CooperativeLevel level)
{
int _level = (int)level;
DWORD flags = 0;
HRESULT hr;
flags |= ((_level & (int)CooperativeLevel::OnlyWhenFocused) ? DISCL_FOREGROUND : DISCL_BACKGROUND);
flags |= ((_level & (int)CooperativeLevel::Exclusive) ? DISCL_EXCLUSIVE : DISCL_NONEXCLUSIVE);
if (_level & (int)CooperativeLevel::DisableWindowsKey)
flags |= DISCL_NOWINKEY;
if (FAILED( hr = device->SetCooperativeLevel( (HWND)host->Handle.ToInt32(), flags ) ))
ThrowHelper::Hr(hr);
if (devtype == DeviceType::Keyboard)
device->SetDataFormat( &c_dfDIKeyboard );
else if (devtype == DeviceType::Mouse)
device->SetDataFormat( &c_dfDIMouse );
}
void Acquire()
{
HRESULT hr;
if (FAILED(hr = device->Acquire()))
ThrowHelper::Hr(hr);
}
void Unacquire()
{
HRESULT hr;
if (FAILED(hr = device->Unacquire()))
ThrowHelper::Hr(hr);
}
void Poll()
{
HRESULT hr;
if (FAILED(hr = device->Poll()))
ThrowHelper::Hr(hr);
}
KeyboardState^ GetKeyboardState()
{
char buffer[256];
HRESULT hr;
if (FAILED(hr = device->GetDeviceState(sizeof(buffer), (void*)buffer)))
ThrowHelper::Hr(hr);
array<bool>^ result = gcnew array<bool>(256);
for( int i=0; i<256; i++ )
result[i] = (buffer[i] & 0x80) != 0;
return gcnew KeyboardState(result);
}
MouseState^ GetMouseState()
{
MouseData mouse;
HRESULT hr;
if (FAILED(hr = device->GetDeviceState(sizeof(mouse), (void*)&mouse)))
ThrowHelper::Hr(hr);
return gcnew MouseState(mouse);
}
JoystickState^ GetJoystickState()
{
DIJOYSTATE state;
HRESULT hr;
if (FAILED(hr = device->GetDeviceState(sizeof(state), (void*)&state)))
ThrowHelper::Hr(hr);
return gcnew JoystickState( &state );
}
~DiInputDevice()
{
safe_release( device );
}
static DiInputDevice^ GetJoystick( InputManager^ manager )
{
IDirectInputDevice8* dev = CreateAndConfigureJoystick( manager->di );
if (dev == nullptr)
return nullptr;
return gcnew DiInputDevice( dev );
}
};
}}

30
BluntDx/InputManager.h Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
namespace BluntDirectX { namespace DirectInput
{
public ref class InputManager
{
private:
internal:
IDirectInput8* di;
public:
InputManager()
{
HINSTANCE hinst = GetModuleHandle(0);
HRESULT hr;
IDirectInput8* _di;
if (FAILED( hr = DirectInput8Create( hinst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&_di, NULL )))
ThrowHelper::Hr(hr);
di = _di;
}
~InputManager()
{
safe_release(di);
}
};
}}

159
BluntDx/JoystickState.h Normal file
View File

@@ -0,0 +1,159 @@
#pragma once
namespace BluntDirectX { namespace DirectInput {
#define joy_axis_limit 1000
#pragma unmanaged
int CALLBACK EnumDevicesCb( const DIDEVICEINSTANCE* inst, void* data )
{
DIDEVICEINSTANCE* pdata = (DIDEVICEINSTANCE*)data;
memcpy( pdata, inst, sizeof( DIDEVICEINSTANCE ) );
return DIENUM_STOP;
}
int CALLBACK EnumDeviceObjectsCb( const DIDEVICEOBJECTINSTANCE* inst, void* data )
{
IDirectInputDevice8* dev = (IDirectInputDevice8*) data;
DIPROPRANGE p;
p.diph.dwSize = sizeof(DIPROPRANGE);
p.diph.dwHeaderSize = sizeof(DIPROPHEADER);
p.diph.dwHow = DIPH_BYID;
p.diph.dwObj = inst->dwType;
p.lMin = -joy_axis_limit;
p.lMax = joy_axis_limit;
HRESULT hr;
if (FAILED(hr = dev->SetProperty( DIPROP_RANGE, &p.diph )))
return DIENUM_STOP;
return DIENUM_CONTINUE;
}
IDirectInputDevice8* CreateAndConfigureJoystick( IDirectInput8* di )
{
DIDEVICEINSTANCE inst;
memset( &inst, 0, sizeof(inst) );
di->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumDevicesCb, (void*)&inst, DIEDFL_ATTACHEDONLY );
if (inst.dwSize == 0)
return nullptr;
IDirectInputDevice8* dev;
HRESULT hr = di->CreateDevice( inst.guidInstance, &dev, NULL );
if (FAILED(hr))
return nullptr;
hr = dev->EnumObjects( EnumDeviceObjectsCb, (void*)dev, DIDFT_AXIS );
if (FAILED(hr)) {
dev->Release();
return nullptr;
}
dev->SetDataFormat( &c_dfDIJoystick );
return dev;
}
#pragma managed
public ref class JoystickState
{
private:
DIJOYSTATE* pstate;
internal:
JoystickState(DIJOYSTATE* state)
{
DIJOYSTATE* p = new DIJOYSTATE;
pstate = p;
memcpy( pstate, state, sizeof( DIJOYSTATE ) );
}
public:
~JoystickState()
{
delete pstate;
}
property float x
{
float get()
{
return (float)pstate->lX / joy_axis_limit;
}
}
property float y
{
float get()
{
return (float)pstate->lY / joy_axis_limit;
}
}
property float z
{
float get()
{
return (float)pstate->lZ / joy_axis_limit;
}
}
property float rx
{
float get()
{
return (float)pstate->lRx / joy_axis_limit;
}
}
property float ry
{
float get()
{
return (float)pstate->lRy / joy_axis_limit;
}
}
property float rz
{
float get()
{
return (float)pstate->lRz / joy_axis_limit;
}
}
property float u
{
float get()
{
return (float)pstate->rglSlider[0] / joy_axis_limit;
}
}
property float v
{
float get()
{
return (float)pstate->rglSlider[1] / joy_axis_limit;
}
}
property int pov
{
int get()
{
return pstate->rgdwPOV[0];
}
}
bool button( int button )
{
return (pstate->rgbButtons[button] & 0x80) != 0;
}
};
}}

77
BluntDx/KeyboardState.h Normal file
View File

@@ -0,0 +1,77 @@
#pragma once
namespace BluntDirectX { namespace DirectInput
{
public enum class Key : unsigned char
{
A = DIK_A, B = DIK_B, C = DIK_C,
D = DIK_D, E = DIK_E, F = DIK_F,
G = DIK_G, H = DIK_H, I = DIK_I,
J = DIK_J, K = DIK_K, L = DIK_L,
M = DIK_M, N = DIK_N, O = DIK_O,
P = DIK_P, Q = DIK_Q, R = DIK_R,
S = DIK_S, T = DIK_T, U = DIK_U,
V = DIK_V, W = DIK_W, X = DIK_X,
Y = DIK_Y, Z = DIK_Z,
D0 = DIK_0, D1 = DIK_1, D2 = DIK_2, D3 = DIK_3, D4 = DIK_4,
D5 = DIK_5, D6 = DIK_6, D7 = DIK_7, D8 = DIK_8, D9 = DIK_9,
ArrowUp = DIK_UPARROW,
ArrowLeft = DIK_LEFTARROW,
ArrowRight = DIK_RIGHTARROW,
ArrowDown = DIK_DOWNARROW,
Space = DIK_SPACE,
Escape = DIK_ESCAPE,
Tab = DIK_TAB,
Enter = DIK_RETURN,
Tilde = DIK_GRAVE,
F1 = DIK_F1,
F2 = DIK_F2,
F3 = DIK_F3,
F4 = DIK_F4,
F5 = DIK_F5,
F6 = DIK_F6,
F7 = DIK_F7,
F8 = DIK_F8,
F9 = DIK_F9,
F10 = DIK_F10,
F11 = DIK_F11,
F12 = DIK_F12,
LeftControl = DIK_LCONTROL,
LeftShift = DIK_LSHIFT,
LeftAlt = DIK_LALT,
Home = DIK_HOME,
End = DIK_END,
PageUp = DIK_PGUP,
PageDown = DIK_PGDN,
RightControl = DIK_RCONTROL,
RightShift = DIK_RSHIFT,
RightAlt = DIK_RALT,
};
public ref class KeyboardState
{
private:
array<bool>^ data;
internal:
KeyboardState( array<bool>^ data ) : data(data) {}
public:
property bool default[ Key ]
{
bool get( Key key )
{
return data[ (int) key ];
}
}
};
}}

66
BluntDx/Mesh.h Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
namespace BluntDirectX { namespace Direct3D
{
generic< typename T > where T : value class
public ref class Mesh
{
internal:
ID3DXMesh* mesh;
public:
Mesh( GraphicsDevice^ device, VertexFormat vertexFormat, array<T>^ vertices, array<short>^ indices,
array<int>^ attributes )
{
ID3DXMesh* m;
HRESULT hr;
if (FAILED( hr =
D3DXCreateMeshFVF( indices->Length / 3, vertices->Length, D3DXMESH_MANAGED, (DWORD)vertexFormat,
device->device, &m)))
ThrowHelper::Hr(hr);
mesh = m;
{
void* vb;
mesh->LockVertexBuffer(0, &vb);
pin_ptr<T> t = &vertices[0];
memcpy( vb, t, vertices->Length * sizeof(T) );
mesh->UnlockVertexBuffer();
}
{
void* ib;
mesh->LockIndexBuffer(0, &ib);
pin_ptr<short> t = &indices[0];
memcpy( ib, t, indices->Length * sizeof(short) );
mesh->UnlockIndexBuffer();
}
{
DWORD* ab;
mesh->LockAttributeBuffer(0, &ab);
pin_ptr<int> t = &attributes[0];
memcpy( ab, t, attributes->Length * sizeof(int) );
mesh->UnlockAttributeBuffer();
}
DWORD* adjacency = new DWORD[ indices->Length ];
mesh->GenerateAdjacency(1e-3f, adjacency);
mesh->OptimizeInplace(D3DXMESHOPT_ATTRSORT, adjacency, NULL, NULL, NULL);
delete[] adjacency;
}
void DrawSubset( int attributeId )
{
mesh->DrawSubset( attributeId );
}
~Mesh()
{
safe_release( mesh );
}
};
}}

67
BluntDx/MouseState.h Normal file
View File

@@ -0,0 +1,67 @@
#pragma once
namespace BluntDirectX { namespace DirectInput {
value class MouseData
{
public:
long x;
long y;
long z;
unsigned char left, right, middle, aux;
};
public ref class MouseState
{
private:
MouseData d;
internal:
MouseState( MouseData d ) : d(d) {}
public:
property bool default[ int ]
{
bool get( int button )
{
unsigned char value = 0;
switch( button )
{
case 0: value = d.left; break;
case 1: value = d.right; break;
case 2: value = d.middle; break;
case 3: value = d.aux; break;
default:
throw gcnew System::Exception("you idiot");
}
return (value & 0x80) != 0;
}
}
property int X
{
int get()
{
return (int)d.x;
}
}
property int Y
{
int get()
{
return (int)d.y;
}
}
property int Z
{
int get()
{
return (int)d.z;
}
}
};
}}

64
BluntDx/SpriteHelper.h Normal file
View File

@@ -0,0 +1,64 @@
#pragma once
namespace BluntDirectX { namespace Direct3D
{
public ref class SpriteHelper
{
internal:
ID3DXSprite* sprite;
public:
SpriteHelper( GraphicsDevice^ device )
{
HRESULT hr;
ID3DXSprite* s;
if (FAILED(
hr = D3DXCreateSprite( device->device, &s )))
ThrowHelper::Hr( hr );
sprite = s;
}
void SetTransform( float sx, float sy, float tx, float ty )
{
D3DXMATRIX m;
memset( &m, 0, sizeof(m));
m._11 = sx; m._22 = sy; m._33 = 1; m._44 = 1;
m._41 = tx; m._42 = ty;
sprite->SetTransform(&m);
}
void Begin()
{
sprite->Begin( D3DXSPRITE_ALPHABLEND );
}
void End()
{
sprite->End();
}
void Flush()
{
sprite->Flush();
}
void Draw( Texture^ texture, int left, int top, int width, int height, int color )
{
RECT r = { left, top, width + left, height + top };
sprite->Draw( (IDirect3DTexture9*)texture->texture, &r, NULL, NULL, color );
}
void Draw( Texture^ texture, int color )
{
sprite->Draw( (IDirect3DTexture9*)texture->texture, NULL, NULL, NULL, color );
}
~SpriteHelper()
{
safe_release( sprite );
}
};
}}

49
BluntDx/Texture.h Normal file
View File

@@ -0,0 +1,49 @@
#pragma once
namespace BluntDirectX { namespace Direct3D
{
public ref class Texture
{
private:
Texture( IDirect3DBaseTexture9* texture ) : texture(texture) {}
internal:
IDirect3DBaseTexture9* texture;
public:
static Texture^ Create( Stream^ stream, GraphicsDevice^ device )
{
stream->Position = 0;
array<unsigned char>^ data = gcnew array<unsigned char>( (int)stream->Length );
stream->Read( data, 0, data->Length );
HRESULT hr;
IDirect3DBaseTexture9* tex;
pin_ptr<unsigned char> p = &data[0];
if (FAILED( hr = D3DXCreateTextureFromFileInMemory( device->device, p, data->Length, (IDirect3DTexture9**)&tex ) ))
throw gcnew InvalidOperationException("Texture load failed");
return gcnew Texture( tex );
}
static Texture^ CreateCube( Stream^ stream, GraphicsDevice^ device )
{
stream->Position = 0;
array<unsigned char>^ data = gcnew array<unsigned char>((int)stream->Length);
stream->Read( data, 0, data->Length );
HRESULT hr;
IDirect3DBaseTexture9* tex;
pin_ptr<unsigned char> p = &data[0];
if (FAILED( hr = D3DXCreateCubeTextureFromFileInMemory( device->device, p, data->Length, (IDirect3DCubeTexture9**)&tex ) ))
throw gcnew InvalidOperationException("Texture load failed");
return gcnew Texture( tex );
}
};
}
}

15
BluntDx/Utilities.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#define safe_release(x) if(x) { (x)->Release(); x = NULL; }
namespace BluntDirectX
{
ref class ThrowHelper
{
public:
static void Hr( HRESULT hr )
{
throw gcnew InvalidOperationException( String::Format("COM error in DirectX, hr={0}", hr) );
}
};
}

161
BluntDx/VertexBuffer.h Normal file
View File

@@ -0,0 +1,161 @@
#pragma once
namespace BluntDirectX { namespace Direct3D
{
public ref class IndexBuffer
{
internal:
IDirect3DIndexBuffer9* buffer;
IDirect3DDevice9* device;
int size;
public:
IndexBuffer( GraphicsDevice^ device, int size )
: size( size ), device( device->device )
{
HRESULT hr;
IDirect3DIndexBuffer9* b;
if (FAILED( hr = this->device->CreateIndexBuffer( sizeof( unsigned short ) * size,
device->HasHardwareVP ? 0 : D3DUSAGE_SOFTWAREPROCESSING, D3DFMT_INDEX16, D3DPOOL_SYSTEMMEM, &b, NULL )))
ThrowHelper::Hr(hr);
buffer = b;
}
void SetData( array<unsigned short>^ data )
{
pin_ptr<unsigned short> pdata = &data[0];
void * ib;
buffer->Lock( 0, sizeof(unsigned short) * size, &ib, D3DLOCK_DISCARD );
memcpy( ib, pdata, sizeof(unsigned short) * size );
buffer->Unlock();
}
void Bind()
{
device->SetIndices( buffer );
}
~IndexBuffer()
{
safe_release( buffer );
}
property int Size { int get() { return size; } }
};
generic<typename T> where T : value class
public ref class FvfVertexBuffer
{
internal:
IDirect3DVertexBuffer9* buffer;
IDirect3DDevice9* device;
int numVertices;
unsigned int fvf;
public:
FvfVertexBuffer( GraphicsDevice^ device, int numVertices, VertexFormat fvf )
: numVertices( numVertices ), device(device->device), fvf((unsigned int)fvf)
{
HRESULT hr;
IDirect3DVertexBuffer9* b;
if (FAILED( hr = device->device->CreateVertexBuffer( sizeof(T) * numVertices,
device->HasHardwareVP ? 0 : D3DUSAGE_SOFTWAREPROCESSING, this->fvf, D3DPOOL_SYSTEMMEM, &b, NULL )))
ThrowHelper::Hr(hr);
buffer = b;
}
void SetData( array<T>^ data )
{
pin_ptr<T> pdata = &data[0];
void* vb;
buffer->Lock( 0, sizeof(T) * numVertices, &vb, D3DLOCK_DISCARD );
memcpy( vb, pdata, sizeof(T) * data->Length );
buffer->Unlock();
}
void Bind( int stream )
{
device->SetStreamSource( stream, buffer, 0, sizeof(T) );
device->SetFVF( fvf );
}
~FvfVertexBuffer()
{
safe_release( buffer );
}
property int Size { int get() { return numVertices; } }
property VertexFormat FVF { VertexFormat get() { return (VertexFormat)fvf; }}
};
generic<typename T> where T : value class
public ref class VertexBuffer
{
internal:
IDirect3DVertexBuffer9* buffer;
IDirect3DVertexDeclaration9* decl;
IDirect3DDevice9* device;
int numVertices;
public:
VertexBuffer( GraphicsDevice^ device, int numVertices )
: numVertices( numVertices ), device(device->device)
{
HRESULT hr;
IDirect3DVertexBuffer9* b;
IDirect3DVertexDeclaration9* d;
D3DVERTEXELEMENT9 elements[] =
{
{0,0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0,12,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,0},
{0,28,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,1},
{0,44,D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE,0},
D3DDECL_END()
};
if (FAILED( hr = device->device->CreateVertexDeclaration( elements, &d ) ))
ThrowHelper::Hr(hr);
decl = d;
if (FAILED( hr = device->device->CreateVertexBuffer( sizeof(T) * numVertices,
D3DUSAGE_DYNAMIC | D3DUSAGE_POINTS |
(device->HasHardwareVP ? 0 : D3DUSAGE_SOFTWAREPROCESSING), 0, D3DPOOL_DEFAULT, &b, NULL )))
ThrowHelper::Hr(hr);
buffer = b;
}
void SetData( array<T>^ data )
{
pin_ptr<T> pdata = &data[0];
void* vb;
buffer->Lock( 0, sizeof(T) * numVertices, &vb, D3DLOCK_DISCARD );
memcpy( vb, pdata, sizeof(T) * data->Length );
buffer->Unlock();
}
void Bind( int stream )
{
device->SetStreamSource( stream, buffer, 0, sizeof(T) );
device->SetVertexDeclaration( decl );
}
~VertexBuffer()
{
safe_release( decl );
safe_release( buffer );
}
property int Size { int get() { return numVertices; } }
};
}}