Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


DX11: How do you draw a triangle?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 dadads   Members   -  Reputation: 142

Like
0Likes
Like

Posted 16 January 2010 - 09:37 AM

Due to the lack of easy-to-understand tutorials on the net, I am currently stuck trying to draw a triangle with DirectX 11. So far I've successfully managed to initialize these objects: - DX11 device - Swap-chain - A render target for rendering to the swap-chain's back-buffer - Device context (this is what you use to draw things, I presume) - A vertex buffer filled with three vertices (for the triangle) I've already set the render target and viewport for the device context. What is the next step to drawing the triangle? i.e. How to make DirectX read from my vertex buffer and draw it? Any help would be appreciated, Thanks

Sponsor:

#2 InvalidPointer   Members   -  Reputation: 1493

Like
0Likes
Like

Posted 16 January 2010 - 09:50 AM

Quote:
Original post by dadads
Due to the lack of easy-to-understand tutorials on the net, I am currently stuck trying to draw a triangle with DirectX 11.

So far I've successfully managed to initialize these objects:
- DX11 device
- Swap-chain
- A render target for rendering to the swap-chain's back-buffer
- Device context (this is what you use to draw things, I presume)
- A vertex buffer filled with three vertices (for the triangle)

I've already set the render target and viewport for the device context.

What is the next step to drawing the triangle?
i.e. How to make DirectX read from my vertex buffer and draw it?

Any help would be appreciated,
Thanks

Same way as in DX10, IIRC. You're just using the immediate context object (you got that from the CreateDevice through one of the parameters) instead of the device object itself.


#3 SiS-Shadowman   Members   -  Reputation: 359

Like
0Likes
Like

Posted 16 January 2010 - 09:58 AM

From what I understand you need to create a vertex- and possibly (though I'm not entirely sure) a pixelshader and an input layout in order to draw your triangle. You can look up the BasicHLSL11 example under "Samples\C++\Direct3D11\BasicHLSL1". You can basically copy their example to render a simple triangle.

Assuming you've created the shaders. You will need to call:
-ID3D11DeviceContext::IASetInputLayout in order to tell D3D what vertex-data is must expect
-ID3D11DeviceContext::IASetVertexBuffers
-ID3D11DeviceContext::VSSetShader
(-ID3D11DeviceContext::PSSetShader)
-ID3D11DeviceContext::DrawIndexed

However I might be wrong with this, as I'm just starting with D3D11 myself (moving from D3D9) and currently struggling with the effects framework.

#4 e3d_ALiVE   Members   -  Reputation: 209

Like
0Likes
Like

Posted 16 January 2010 - 10:02 AM

he does't have index buffer for triangle
so i suggest him to use just ID3D11DeviceContext::Draw or ID3D11DeviceContext::DrawAuto if possible
and to not hurt yourself with setting different VS/PS states he can use ID3DXEffect(but u have to compile it first)

#5 Erik Rufelt   Crossbones+   -  Reputation: 4467

Like
0Likes
Like

Posted 16 January 2010 - 10:03 AM

The D3D10 Basic Tutorials are pretty easy to follow. D3D11 is almost exactly the same, most of the time just renamed from 10 to 11.

EDIT: With 11 it might be easier to skip the effect framework in the beginning though, as others have said there are problems with it.

#6 Jason Z   Crossbones+   -  Reputation: 6108

Like
0Likes
Like

Posted 16 January 2010 - 10:50 AM

JollyJeffers posted a very simple starter application in his journal nearly a year ago now...

Keep in mind that it was developed when DX11 was still in beta form, but the basic drawing sequence should still be the same. I hope that helps!

#7 dadads   Members   -  Reputation: 142

Like
0Likes
Like

Posted 17 January 2010 - 06:12 AM

*vomits

So much to do for a triangle!

Thanks for the info, I'll check them out.

#8 manders   Members   -  Reputation: 128

Like
0Likes
Like

Posted 21 January 2010 - 10:19 AM

Hi,

Here's source code for a pretty minimal app to draw a triangle in D3D11:


//--------------------------------------------------------------------------------------
// File: Tutorial01.cpp
//
// This application displays a triangle rendered using Direct3D 11.
//
// Concepts introduced in this tutorial:
// Creating a device and swap chain
// Compiling and creating shaders
// Setting up the render target and viewport
// Setting up a simple vertex buffer and its input layout
// Clearing the render target
// Drawing a triangle
// Presenting the rendered frame to the display
//
// Copyright © Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include <windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>


//--------------------------------------------------------------------------------------
// Structures
//--------------------------------------------------------------------------------------
struct SimpleVertex
{
FLOAT Pos[3]; // (X, Y, Z) coordinates of each vertex
};


//--------------------------------------------------------------------------------------
// Global Variables
//--------------------------------------------------------------------------------------
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
IDXGISwapChain* g_pSwapChain = NULL;
ID3D11Device* g_pDevice = NULL;
ID3D11DeviceContext* g_pContext = NULL;
ID3D11RenderTargetView* g_pRenderTargetView = NULL;
ID3D11InputLayout* g_pInputLayout = NULL;
ID3D11Buffer* g_pVertexBuffer = NULL;
ID3D11VertexShader* g_pVertexShader = NULL;
ID3D11PixelShader* g_pPixelShader = NULL;


//--------------------------------------------------------------------------------------
// Vertex shader and pixel shader source code
//--------------------------------------------------------------------------------------
CHAR* g_strVS =
"void VS( in float4 posIn : POSITION,\n"
" out float4 posOut : SV_Position )\n"
"{\n"
" // Output the vertex position, unchanged\n"
" posOut = posIn;\n"
"}\n";

CHAR* g_strPS =
"void PS( out float4 colorOut : SV_Target )\n"
"{\n"
" // Make each pixel yellow, with alpha = 1\n"
" colorOut = float4( 1.0f, 1.0f, 0.0f, 1.0f );\n"
"}\n";


//--------------------------------------------------------------------------------------
// Forward declarations
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
HRESULT InitDeviceAndSwapChain();
HRESULT InitDeviceObjects();
void InitDeviceContext();
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam );
void Render();
void CleanupDevice();


//--------------------------------------------------------------------------------------
// Entry point to the program. Initializes everything and goes into a message processing
// loop. Idle time is used to render the scene.
//--------------------------------------------------------------------------------------
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;

if( FAILED( InitDeviceAndSwapChain() ) )
return 0;

if( FAILED( InitDeviceObjects() ) )
{
CleanupDevice();
return 0;
}

InitDeviceContext();

// Main message loop
MSG msg = { 0 };
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}

CleanupDevice();

return (int)msg.wParam;
}


//--------------------------------------------------------------------------------------
// Register class and create window
//--------------------------------------------------------------------------------------
HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
{
// Register class
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"TutorialWindowClass";
wcex.hIconSm = NULL;
if( !RegisterClassEx( &wcex ) )
return E_FAIL;

// Create window
g_hInst = hInstance;
RECT rc = { 0, 0, 640, 480 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );
g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 11 Tutorial 1: Triangle",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top,
NULL, NULL, hInstance, NULL );
if( !g_hWnd )
return E_FAIL;

return S_OK;
}


//--------------------------------------------------------------------------------------
// Create the Direct3D device and DXGI swap chain
//--------------------------------------------------------------------------------------
HRESULT InitDeviceAndSwapChain()
{
HRESULT hr = S_OK;

RECT rc;
GetClientRect( g_hWnd, &rc );
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;

UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = _countof( driverTypes );

D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = _countof(featureLevels);
D3D_FEATURE_LEVEL featureLevelOut;

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 = g_hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;

D3D_DRIVER_TYPE driverType;
for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )
{
driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain( NULL, driverType, NULL, createDeviceFlags,
featureLevels, numFeatureLevels, D3D11_SDK_VERSION,
&sd, &g_pSwapChain, &g_pDevice, &featureLevelOut,
&g_pContext );
if( SUCCEEDED( hr ) )
break;
}

return hr;
}


//--------------------------------------------------------------------------------------
// Use the Direct3D device to create additional objects needed for rendering
//--------------------------------------------------------------------------------------
HRESULT InitDeviceObjects()
{
HRESULT hr = S_OK;

// Create the render target view
ID3D11Texture2D* pRenderTargetTexture;
hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D11Texture2D ), (LPVOID*)&pRenderTargetTexture );
if( FAILED( hr ) )
return hr;

hr = g_pDevice->CreateRenderTargetView( pRenderTargetTexture, NULL, &g_pRenderTargetView );
pRenderTargetTexture->Release();
if( FAILED( hr ) )
return hr;

// Compile and create the vertex shader
DWORD dwShaderFlags = D3D10_SHADER_ENABLE_STRICTNESS;
#ifdef _DEBUG
dwShaderFlags |= D3D10_SHADER_DEBUG;
#endif
ID3D10Blob* pBlobVS = NULL;
ID3D10Blob* pBlobError = NULL;
hr = D3DCompile( g_strVS, lstrlenA( g_strVS ) + 1, "VS", NULL, NULL, "VS",
"vs_4_0", dwShaderFlags, 0, &pBlobVS, &pBlobError );
if( FAILED( hr ) )
{
if( pBlobError != NULL )
{
OutputDebugStringA( (CHAR*)pBlobError->GetBufferPointer() );
pBlobError->Release();
}
return hr;
}
hr = g_pDevice->CreateVertexShader( pBlobVS->GetBufferPointer(), pBlobVS->GetBufferSize(),
NULL, &g_pVertexShader );
if( FAILED( hr ) )
return hr;

// Compile and create the pixel shader
ID3D10Blob* pBlobPS = NULL;
hr = D3DCompile( g_strPS, lstrlenA( g_strPS ) + 1, "PS", NULL, NULL, "PS",
"ps_4_0", dwShaderFlags, 0, &pBlobPS, &pBlobError );
if( FAILED( hr ) )
{
if( pBlobError != NULL )
{
OutputDebugStringA( (CHAR*)pBlobError->GetBufferPointer() );
pBlobError->Release();
}
return hr;
}
hr = g_pDevice->CreatePixelShader( pBlobPS->GetBufferPointer(), pBlobPS->GetBufferSize(),
NULL, &g_pPixelShader );
if( FAILED( hr ) )
return hr;
pBlobPS->Release();

// Create the input layout
D3D11_INPUT_ELEMENT_DESC elements[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = _countof( elements );

hr = g_pDevice->CreateInputLayout( elements, numElements, pBlobVS->GetBufferPointer(),
pBlobVS->GetBufferSize(), &g_pInputLayout );
if( FAILED( hr ) )
return hr;

pBlobVS->Release();

// Create the vertex buffer
SimpleVertex vertices[] =
{
0.0f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
};
D3D11_BUFFER_DESC bd;
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( vertices );
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
bd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA initData;
initData.pSysMem = vertices;
hr = g_pDevice->CreateBuffer( &bd, &initData, &g_pVertexBuffer );
if( FAILED( hr ) )
return hr;

return hr;
}


//--------------------------------------------------------------------------------------
// Set up the device context
//--------------------------------------------------------------------------------------
void InitDeviceContext()
{
g_pContext->IASetInputLayout( g_pInputLayout );

UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

g_pContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

g_pContext->VSSetShader( g_pVertexShader, NULL, 0 );

g_pContext->PSSetShader( g_pPixelShader, NULL, 0 );

RECT rc;
GetClientRect( g_hWnd, &rc );
D3D11_VIEWPORT vp;
vp.Width = (FLOAT)(rc.right - rc.left);
vp.Height = (FLOAT)(rc.bottom - rc.top);
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
g_pContext->RSSetViewports( 1, &vp );

g_pContext->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );
}


//--------------------------------------------------------------------------------------
// Called every time the application receives a message
//--------------------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;

switch( message )
{
case WM_PAINT:
hdc = BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps );
break;

case WM_CHAR:
if( wParam == VK_ESCAPE )
DestroyWindow( hWnd );
break;

case WM_DESTROY:
PostQuitMessage( 0 );
break;

default:
return DefWindowProc( hWnd, message, wParam, lParam );
}

return 0;
}


//--------------------------------------------------------------------------------------
// Render a frame
//--------------------------------------------------------------------------------------
void Render()
{
// Clear the render target to dark blue
float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red, green, blue, alpha
g_pContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );

// Render a triangle
g_pContext->Draw( 3, 0 );

// Show the rendered frame on the screen
g_pSwapChain->Present( 0, 0 );
}


//--------------------------------------------------------------------------------------
// Destroy the objects we've created
//--------------------------------------------------------------------------------------
void CleanupDevice()
{
if( g_pVertexShader != NULL )
g_pVertexShader->Release();
if( g_pPixelShader != NULL )
g_pPixelShader->Release();
if( g_pVertexBuffer != NULL )
g_pVertexBuffer->Release();
if( g_pInputLayout != NULL )
g_pInputLayout->Release();
if( g_pRenderTargetView != NULL )
g_pRenderTargetView->Release();
if( g_pContext != NULL )
g_pContext->Release();
if( g_pSwapChain != NULL )
g_pSwapChain->Release();
if( g_pDevice != NULL )
g_pDevice->Release();
}



Hope that helps.

-Mike




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS