Original Post
I was following microsoft's tutorials on DX10 and I've got to the cube drawing and rotating but the cube isn't being rendered. When my cube wouldn't render I tried building Microsoft's code and the cube didn't render with their code either. I don't know why as I'm completely new to D3D. Here's my code: I noticed that if I change: D3D_Device->DrawIndexed( 36, 0, 0 ) to D3D_Device->Draw( 12, 0 ) I get a yellow triangle at the bottom of the screen?
#include <windows.h>
#include <d3d10.h>
#include <d3dx10.h>
#pragma comment (lib, "d3d10.lib")
#pragma comment (lib, "d3dx10.lib")
struct BasicVertex { D3DXVECTOR3 Position; D3DXVECTOR4 Color; };
int Width = 640, Height = 480;
HWND hWnd;
HINSTANCE hInst;
D3D10_DRIVER_TYPE D3D_DriverType = D3D10_DRIVER_TYPE_NULL;
ID3D10Device* D3D_Device = NULL;
IDXGISwapChain* SwapChain = NULL;
ID3D10RenderTargetView* RenderTargetView = NULL;
ID3D10Effect* Effect = NULL;
ID3D10EffectTechnique* Technique = NULL;
ID3D10InputLayout* VertexLayout = NULL;
ID3D10Buffer* VertexBuffer = NULL;
ID3D10Buffer* IndexBuffer = NULL;
ID3D10EffectMatrixVariable* WorldVariable = NULL;
ID3D10EffectMatrixVariable* ViewVariable = NULL;
ID3D10EffectMatrixVariable* ProjectionVariable = NULL;
D3DXMATRIX World;
D3DXMATRIX View;
D3DXMATRIX Projection;
LRESULT CALLBACK WndProc( HWND , UINT, WPARAM, LPARAM );
HRESULT InitD3D( void );
void Cleanup( void );
void Render ( void );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
WNDCLASSEX wc;
ZeroMemory( &wc, sizeof( WNDCLASSEX ) );
wc.cbSize = sizeof( WNDCLASSEX );
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = TEXT( "Win32Test" );
if( !RegisterClassEx( &wc ) )
{
MessageBox( NULL, TEXT( "Unable to register window class." ), TEXT( "Error" ), MB_OK | MB_ICONERROR );
return FALSE;
}
hInst = hInstance;
hWnd = CreateWindowEx( NULL, wc.lpszClassName, TEXT( "Win32 Test" ), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, Width, Height, NULL, NULL, hInstance, NULL);
if( !hWnd )
{
MessageBox( NULL, TEXT( "Unable to create window." ), TEXT( "Error" ), MB_OK | MB_ICONERROR );
return FALSE;
}
ShowWindow( hWnd, nShowCmd );
if( FAILED( InitD3D() ) )
{
MessageBox( NULL, TEXT( "Unable to initialize Direct3D 10." ), TEXT( "Error" ), MB_OK | MB_ICONERROR );
return FALSE;
}
MSG msg = {0};
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
Render();
}
Cleanup();
return msg.wParam;
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT pc;
HDC hdc;
switch( Message )
{
case WM_PAINT:
hdc = BeginPaint( hWnd, &pc );
EndPaint( hWnd, &pc );
break;
case WM_DESTROY:
PostQuitMessage( 0 );
break;
default:
return DefWindowProc( hWnd, Message, wParam, lParam );
}
return 0;
}
HRESULT InitD3D( void )
{
HRESULT Result = S_OK;
D3D10_DRIVER_TYPE DriverTypes[] = { D3D10_DRIVER_TYPE_HARDWARE, D3D10_DRIVER_TYPE_REFERENCE, };
UINT numDriverTypes = sizeof( DriverTypes ) / sizeof( DriverTypes[0] );
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof( sd ) );
sd.BufferCount = 1;
sd.BufferDesc.Width = Width;
sd.BufferDesc.Height = Height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
for( UINT DriverTypeIndex = 0; DriverTypeIndex < numDriverTypes; DriverTypeIndex++ )
{
D3D_DriverType = DriverTypes[DriverTypeIndex];
Result = D3D10CreateDeviceAndSwapChain( NULL, D3D_DriverType, NULL, D3D10_CREATE_DEVICE_DEBUG,
D3D10_SDK_VERSION, &sd, &SwapChain, &D3D_Device );
if( SUCCEEDED( Result ) )
break;
}
if( FAILED( Result ) )
return Result;
ID3D10Texture2D* BackBuffer;
Result = SwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&BackBuffer );
if( FAILED( Result ) )
return Result;
Result = D3D_Device->CreateRenderTargetView( BackBuffer, NULL, &RenderTargetView );
BackBuffer->Release();
if( FAILED( Result ) )
return Result;
D3D_Device->OMSetRenderTargets( 1, &RenderTargetView, NULL );
D3D10_VIEWPORT vp;
vp.Width = Width;
vp.Height = Height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
D3D_Device->RSSetViewports( 1, &vp );
Result = D3DX10CreateEffectFromFile( TEXT( "Basic.fx" ), NULL, NULL, "fx_4_0", D3D10_SHADER_DEBUG, 0,
D3D_Device, NULL, NULL, &Effect, NULL, NULL );
if( FAILED( Result ) )
{
MessageBox( NULL, TEXT( "The FX file cannot be located." ), TEXT( "Error" ), MB_OK | MB_ICONERROR);
return Result;
}
Technique = Effect->GetTechniqueByName( "Render" );
WorldVariable = Effect->GetVariableByName( "World" )->AsMatrix();
ViewVariable = Effect->GetVariableByName( "View" )->AsMatrix();
ProjectionVariable = Effect->GetVariableByName( "Projection" )->AsMatrix();
D3D10_INPUT_ELEMENT_DESC Layout[] =
{
{ TEXT( "POSITION" ), 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ TEXT( "COLOR" ), 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = sizeof( Layout ) / sizeof( Layout[0] );
D3D10_PASS_DESC PassDesc;
Technique->GetPassByIndex( 0 )->GetDesc( &PassDesc );
Result = D3D_Device->CreateInputLayout( Layout, numElements, PassDesc.pIAInputSignature,
PassDesc.IAInputSignatureSize, &VertexLayout );
if( FAILED( Result ) )
return Result;
D3D_Device->IASetInputLayout( VertexLayout );
BasicVertex Vertices[] =
{
{ D3DXVECTOR3( -1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ D3DXVECTOR3( 1.0f, 1.0f, -1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 0.0f, 1.0f ) },
{ D3DXVECTOR3( 1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ D3DXVECTOR3( -1.0f, 1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 0.0f, 1.0f ) },
{ D3DXVECTOR3( -1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 0.0f, 1.0f, 1.0f ) },
{ D3DXVECTOR3( 1.0f, -1.0f, -1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 0.0f, 1.0f ) },
{ D3DXVECTOR3( 1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ D3DXVECTOR3( -1.0f, -1.0f, 1.0f ), D3DXVECTOR4( 0.0f, 0.0f, 0.0f, 1.0f ) },
};
D3D10_BUFFER_DESC bd;
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = sizeof( BasicVertex ) * 8;
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D10_SUBRESOURCE_DATA InitialData;
InitialData.pSysMem = Vertices;
InitialData.SysMemPitch = sizeof( Vertices );
InitialData.SysMemSlicePitch = sizeof( Vertices );
Result = D3D_Device->CreateBuffer( &bd, &InitialData, &VertexBuffer );
if( FAILED( Result ) )
return Result;
BasicVertex *Data = NULL;
if( SUCCEEDED( VertexBuffer->Map( D3D10_MAP_WRITE, 0, reinterpret_cast< void** >( &Data ) ) ) )
{
memcpy( Data, VertexArray, sizeof( SimpleVertex ) * 8 );
VertexBuffer->Unmap( );
}
UINT Stride = sizeof( BasicVertex );
UINT Offset = 0;
D3D_Device->IASetVertexBuffers( 0, 1, &VertexBuffer, &Stride, &Offset );
DWORD Indices[] =
{
3,1,0,
2,1,3,
0,5,4,
1,5,0,
3,4,7,
0,4,3,
1,6,5,
2,6,1,
2,7,6,
3,7,2,
6,4,5,
7,4,6,
};
bd.Usage = D3D10_USAGE_DEFAULT;
bd.ByteWidth = sizeof( DWORD ) * 36;
bd.BindFlags = D3D10_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
InitialData.pSysMem = Indices;
InitialData.SysMemPitch = sizeof( Indices );
InitialData.SysMemSlicePitch = sizeof( Indices );
Result = D3D_Device->CreateBuffer( &bd, &InitialData, &IndexBuffer );
if( FAILED( Result ) )
return Result;
D3D_Device->IASetIndexBuffer( IndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
D3D_Device->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
D3DXMatrixIdentity( &World );
D3DXVECTOR3 Eye( 0.0f, 1.0f, -5.0f );
D3DXVECTOR3 At( 0.0f, 1.0f, 0.0f );
D3DXVECTOR3 Up( 0.0f, 1.0f, 0.0f );
D3DXMatrixLookAtLH( &View, &Eye, &At, &Up );
D3DXMatrixPerspectiveFovLH( &Projection, ( float )D3DX_PI * 0.5f, Width / ( FLOAT )Height, 0.1f, 100.0f );
return S_OK;
}
void Render( void )
{
static float t = 0.0f;
if( DriverType == D3D10_DRIVER_TYPE_REFERENCE )
{
t += (float)D3DX_PI * 0.0125f;
}
else
{
static DWORD TimeStart = 0;
DWORD TimeCur = GetTickCount();
if( TimeStart == 0 )
TimeStart = TimeCur;
t = ( TimeCur - TimeStart ) / 1000.0f;
}
D3DXMatrixRotationY( &World, t );
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 0.0f };
D3D_Device->ClearRenderTargetView( RenderTargetView, ClearColor );
WorldVariable->SetMatrix( (float*)&World );
ViewVariable->SetMatrix( (float*)&View );
ProjectionVariable->SetMatrix( (float*)&Projection );
D3D10_TECHNIQUE_DESC TechDesc;
Technique->GetDesc( &TechDesc );
for( UINT p = 0; p < TechDesc.Passes; p++ )
{
Technique->GetPassByIndex( p )->Apply( 0 );
D3D_Device->DrawIndexed( 36, 0, 0 );
}
SwapChain->Present( 0, 0 );
}
void Cleanup( void )
{
if( D3D_Device ) D3D_Device->ClearState();
if( VertexBuffer ) VertexBuffer->Release();
if( VertexLayout ) VertexLayout->Release();
if( Effect ) Effect->Release();
if( RenderTargetView ) RenderTargetView->Release();
if( SwapChain ) SwapChain->Release();
if( D3D_Device ) D3D_Device->Release();
}