User Tools

Site Tools


Tutorial 2 - Rendering a Triangle

by Richard Russell, August 2015

Note that the code in this tutorial requires Windows 8.1 or Windows 10

This tutorial is closely based on Microsoft's Direct 3D 11 Tutorial 2 but with the code translated from C++ to BBC BASIC for Windows. You should refer to the original for a detailed explanation of the code.


In the previous tutorial, we built a minimal Direct3D 11 application that outputs a single colour to the window. In this tutorial, we will extend the application to render a single triangle on the screen. We will go through the process to set up the data structures associated with a triangle.

The outcome of this tutorial is a window with a triangle rendered to the centre of the window.


The source files, libraries etc. may be downloaded from here.

Input Layout

The GPU must know about the vertex layout in order to extract correct attributes from the buffer. To accomplish this requires the use of an input layout:

        REM Define the input layout:
        DIM layout{(0)} = D3D11_INPUT_ELEMENT_DESC{}
        sn0$ = "POSITION" + CHR$(0)
        layout{(0)}.SemanticName% = !^sn0$
        layout{(0)}.Format% = DXGI_FORMAT_R32G32B32_FLOAT
        layout{(0)}.AlignedByteOffset% = 0
        layout{(0)}.InputSlotClass% = D3D11_INPUT_PER_VERTEX_DATA
        numElements% = DIM(layout{()},1) + 1
        REM Create the input layout:
        SYS ID3D11Device.CreateInputLayout%, pd3dDevice%, layout{(0)}, numElements%, bp%, bs%, \
        \   ^pVertexLayout% TO hr%
        SYS ID3D10Blob.Release%, pVSBlob%
        IF hr% <> 0 OR pVertexLayout% = 0 ERROR 100, "ID3D11Device::CreateInputLayout failed: "+STR$~hr%
        REM Set the input layout:
        SYS ID3D11DeviceContext.IASetInputLayout%, pImmediateContext%, pVertexLayout%

Vertex Layout

In this tutorial, we are only working with the position of the vertices. Therefore, we define our vertex structure with a single field of the type XMFLOAT3. This type is a vector of three floating-points components, which is typically the data type used for position in 3D:

        DIM SimpleVertex{} = XMFLOAT3{}

Creating Vertex Buffer

One thing that we will need to do during initialization is to create the vertex buffer that holds the vertex data. The coordinates in the vertices array are chosen so that we see a triangle in the middle of our application window when rendered with our shaders:

        REM Create vertex buffer:
        DIM vertices{(2)} = SimpleVertex{}
        vertices{(0)}.x% = 0
        vertices{(0)}.y% = FN_f4(0.5)
        vertices{(0)}.z% = FN_f4(0.5)
        vertices{(1)}.x% = FN_f4(0.5)
        vertices{(1)}.y% = FN_f4(-0.5)
        vertices{(1)}.z% = FN_f4(0.5)
        vertices{(2)}.x% = FN_f4(-0.5)
        vertices{(2)}.y% = FN_f4(-0.5)
        vertices{(2)}.z% = FN_f4(0.5)
        DIM bd{} = D3D11_BUFFER_DESC{}
        bd.Usage% = D3D11_USAGE_DEFAULT
        bd.ByteWidth% = DIM(SimpleVertex{}) * (DIM(vertices{()},1)+1)
        bd.BindFlags% = D3D11_BIND_VERTEX_BUFFER
        bd.CPUAccessFlags% = 0
        DIM InitData{} = D3D11_SUBRESOURCE_DATA{}
        InitData.pSysMem% = vertices{(0)}
        SYS ID3D11Device.CreateBuffer%, pd3dDevice%, bd{}, InitData{}, ^pVertexBuffer% TO hr%
        IF hr% <> 0 OR pVertexBuffer% = 0 ERROR 100, "ID3D11Device::CreateBuffer failed: "+STR$~hr%
        REM Set vertex buffer:
        stride% = DIM(SimpleVertex{})
        offset% = 0
        SYS ID3D11DeviceContext.IASetVertexBuffers%, pImmediateContext%, 0, 1, \
        \                                   ^pVertexBuffer%, ^stride%, ^offset%

Primitive Topology

Primitive topology refers to how the GPU obtains the three vertices it requires to render a triangle. What if we want to render two triangles? One way is to send 6 vertices to the GPU. The first three vertices define the first triangle and the second three vertices define the second triangle. This topology is called a triangle list:

        REM Set primitive topology:
        SYS ID3D11DeviceContext.IASetPrimitiveTopology%, pImmediateContext%, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST

Rendering the Triangle

The final item missing is the code that does the actual rendering of the triangle. We have created two shaders to for rendering, the vertex shader and pixel shader. The vertex shader is responsible for transforming the individual vertices of the triangles to their correct locations and the pixel shader is responsible for calculating the final output colour for each pixel of the triangle. This is covered in more detail in the next tutorial:

        REM Render a triangle:
        SYS ID3D11DeviceContext.VSSetShader%, pImmediateContext%, pVertexShader%, NULL, 0
        SYS ID3D11DeviceContext.PSSetShader%, pImmediateContext%, pPixelShader%, NULL, 0
        SYS ID3D11DeviceContext.Draw%, pImmediateContext%, 3, 0
This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
tutorial_202_20-_20rendering_20a_20triangle.txt · Last modified: 2018/04/13 22:29 by richardrussell