Jump to content

  • Log In with Google      Sign In   
  • Create Account


DirectX11 Setting up the Constant Buffer help


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 Xooch   Members   -  Reputation: 179

Like
0Likes
Like

Posted 05 November 2012 - 11:41 AM

Hey there,

I've just setup my Constant Buffer in DirectX11, everything seems to be going fine, but the "IASetVertexBuffers" seems to be breaking while I debug, I havn't any idea why, could an experienced programmer please take a look and tell me if I have made a mistake in Syntax or something?

here is a screenshot of where it breaks: http://img194.imageshack.us/img194/6109/herrrx.jpg

Thanks

Object.cpp
#include "Object.h"
Object::Object()
{
}
Object::~Object()
{
}
void Object::Render(ID3D11DeviceContext * pImmediateContext)
{
OFFSET Offset;
Offset.X = 0.5f;
Offset.Y = 0.2f;
Offset.Z = 0.7f;
pImmediateContext->UpdateSubresource(pCBuffer, 0, 0, &Offset, 0, 0);
    // Render a triangle
VertexShader(pImmediateContext);
PixelShader(pImmediateContext);
    pImmediateContext->Draw( 3, 0 );
}

void Object::VertexShader(ID3D11DeviceContext * pImmediateContext)
{
pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
}

void Object::PixelShader(ID3D11DeviceContext * pImmediateContext)
{
pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
}

HRESULT Object::CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )
{
    HRESULT hr = S_OK;
    DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
    // Setting this flag improves the shader debugging experience, but still allows
    // the shaders to be optimized and to run exactly the way they will run in
    // the release configuration of this program.
    dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
    ID3DBlob* pErrorBlob;
    hr = D3DX11CompileFromFile( szFileName,
  NULL,
  NULL,
  szEntryPoint,
  szShaderModel,
	    dwShaderFlags,
  0,
  NULL,
  ppBlobOut,
  &pErrorBlob,
  NULL );
    if( FAILED(hr) )
    {
	    if( pErrorBlob != NULL )
		    OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
	    if( pErrorBlob ) pErrorBlob->Release();
	    return hr;
    }
    if( pErrorBlob ) pErrorBlob->Release();
    return S_OK;
}

HRESULT Object::InitObject(ID3D11Device * device, ID3D11DeviceContext * pImmediateContext)
{
HRESULT hr = S_OK;

    // Compile the vertex shader
    ID3DBlob* pVSBlob = NULL;
    hr = CompileShaderFromFile( L"Shader.fx",
	    "VShader",
	    "vs_4_0",
	    &pVSBlob );

    if( FAILED( hr ) )
    {
	    MessageBox( NULL,
				    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
	    return hr;
    }

// Create the vertex shader
hr = device->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );
if( FAILED( hr ) )
{
  pVSBlob->Release();
	    return hr;
}

    // Define the input layout
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
	    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
  {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
    };
UINT numElements = ARRAYSIZE( layout );
    // Create the input layout
hr = device->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
										  pVSBlob->GetBufferSize(), &g_pVertexLayout );
pVSBlob->Release();
if( FAILED( hr ) )
	    return hr;
    // Set the input layout
    pImmediateContext->IASetInputLayout( g_pVertexLayout );
// Compile the pixel shader
ID3DBlob* pPSBlob = NULL;
    hr = CompileShaderFromFile( L"Shader.fx",
	    "PShader",
	    "ps_4_0",
	    &pPSBlob );
    if( FAILED( hr ) )
    {
	    MessageBox( NULL,
				    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
	    return hr;
    }
// Create the pixel shader
hr = device->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );
pPSBlob->Release();
    if( FAILED( hr ) )
	    return hr;
    // Create vertex buffer
    D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = 16;
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
/*
    D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = vertices;
*/
    hr = device->CreateBuffer( &bd, NULL, &pCBuffer );
pImmediateContext->VSSetConstantBuffers(0, 1, &pCBuffer);
    if( FAILED( hr ) )
	    return hr;
return hr;
}
void Object::SetupVertex(ID3D11DeviceContext * pImmediateContext)
{
    // Set vertex buffer
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
    // Set primitive topology
    pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
}

void Object::CleanupObject()
{
    if( g_pVertexBuffer ) g_pVertexBuffer->Release();
    if( g_pVertexLayout ) g_pVertexLayout->Release();
    if( g_pVertexShader ) g_pVertexShader->Release();
    if( g_pPixelShader ) g_pPixelShader->Release();
}

Shader.fx
//Created by Tim Lawton 2012
//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
//Constant Buffer
cbuffer ConstantBuffer
{
float3 Offset;
}

//Struct to return two values
struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
    // create a VOut struct
    VOut output;
    // set the output values
    output.position = position;
output.position.x += Offset.x;
    output.position.y += Offset.y;
    output.position.xy *= Offset.z;
    output.color = color;
    // return the output values
    return output;
}
//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
    return color;
}

Edited by Xuchilbara, 05 November 2012 - 11:43 AM.


Sponsor:

#2 kauna   Crossbones+   -  Reputation: 2290

Like
0Likes
Like

Posted 05 November 2012 - 12:28 PM

Where do you create your vertex buffer? According to your code, you don't create a vertex buffer.

Cheers!

#3 AlzPatz   Members   -  Reputation: 144

Like
0Likes
Like

Posted 05 November 2012 - 12:57 PM

As Kauna says... You sort of set off trying to create one and then don't

// Create vertex buffer
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = 16;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;


//You comment out your vertices sub resource??

/*
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
*/


//You dont create the buffer!
something like...device->Createe buffer(&bd, &initdata, &vertexbuffer) or whatever the names are exactly!

hr = device->CreateBuffer( &bd, NULL, &pCBuffer );

#4 Xooch   Members   -  Reputation: 179

Like
0Likes
Like

Posted 05 November 2012 - 03:50 PM

ok guys, taken what you said and made some changes, yet I still get the same problems. I've commented it so it might be easier to read.

The constant buffer is created and Setup at the bottom of Object::InitObject. and then the UpdateSubresource is in Object::Render to update the constant buffer, yet I still get the same problem in the screenshot with the "pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);"

I get the feeling something is suppose to be passed from InitObject into the UpdateSubresources parameters, but I'm not sure what. If you could take a look at this updated code and point me in the right direction that'd be great, thanks!


Object.cpp
#include "Object.h"
Object::Object()
{
}
Object::~Object()
{
}
void Object::Render(ID3D11DeviceContext * pImmediateContext)
{
OFFSET Offset;
Offset.X = 0.5f;
Offset.Y = 0.2f;
Offset.Z = 0.7f;
pImmediateContext->UpdateSubresource(g_pCBuffer, 0, 0, &Offset, 0, 0);
// select which vertex buffer to display
    UINT stride = sizeof(VERTEX);
    UINT offset = 0;
    pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
    // select which primtive type we are using
    pImmediateContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    // Render a triangle
VertexShader(pImmediateContext);
PixelShader(pImmediateContext);
    pImmediateContext->Draw( 3, 0 );
}
void Object::InitGraphics(ID3D11Device * device, ID3D11DeviceContext * pImmediateContext)
{
	 // create a triangle using the VERTEX struct
    VERTEX OurVertices[] =
    {
	    {0.0f, 0.5f, 0.0f, D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f)},
	    {0.45f, -0.5, 0.0f, D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f)},
	    {-0.45f, -0.5f, 0.0f, D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f)}
    };

    // create the vertex buffer
    D3D11_BUFFER_DESC bd;
    ZeroMemory(&bd, sizeof(bd));
    bd.Usage = D3D11_USAGE_DYNAMIC;			    // write access access by CPU and GPU
    bd.ByteWidth = sizeof(VERTEX) * 3;			 // size is the VERTEX struct * 3
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;	   // use as a vertex buffer
    bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;    // allow CPU to write in buffer
    device->CreateBuffer(&bd, NULL, &g_pVertexBuffer);	   // create the buffer

    // copy the vertices into the buffer
    D3D11_MAPPED_SUBRESOURCE ms;
    pImmediateContext->Map(g_pVertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);    // map the buffer
    memcpy(ms.pData, OurVertices, sizeof(OurVertices));				 // copy the data
    pImmediateContext->Unmap(g_pVertexBuffer, NULL);									  // unmap the buffer
}

void Object::VertexShader(ID3D11DeviceContext * pImmediateContext)
{
pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
}

void Object::PixelShader(ID3D11DeviceContext * pImmediateContext)
{
pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
}

HRESULT Object::CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )
{
    HRESULT hr = S_OK;
    DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    // Set the D3DCOMPILE_DEBUG flag to embed debug information in the shaders.
    // Setting this flag improves the shader debugging experience, but still allows
    // the shaders to be optimized and to run exactly the way they will run in
    // the release configuration of this program.
    dwShaderFlags |= D3DCOMPILE_DEBUG;
#endif
    ID3DBlob* pErrorBlob;
    hr = D3DX11CompileFromFile( szFileName,
  NULL,
  NULL,
  szEntryPoint,
  szShaderModel,
	    dwShaderFlags,
  0,
  NULL,
  ppBlobOut,
  &pErrorBlob,
  NULL );
    if( FAILED(hr) )
    {
	    if( pErrorBlob != NULL )
		    OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
	    if( pErrorBlob ) pErrorBlob->Release();
	    return hr;
    }
    if( pErrorBlob ) pErrorBlob->Release();
    return S_OK;
}

HRESULT Object::InitObject(ID3D11Device * device, ID3D11DeviceContext * pImmediateContext)
{
HRESULT hr = S_OK;
//------------------
// VERTEX SHADER
//------------------
    // Compile the vertex shader
    ID3DBlob* pVSBlob = NULL;
    hr = CompileShaderFromFile( L"Shader.fx",
	    "VShader",
	    "vs_4_0",
	    &pVSBlob );

//Error Handling
    if( FAILED( hr ) )
    {
	    MessageBox( NULL,
				    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
	    return hr;
    }

// Create the vertex shader
hr = device->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );
if( FAILED( hr ) )
{
  pVSBlob->Release();
	    return hr;
}

    //Allows the Vertex Shader to return 2 values, Position and Color
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
	    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
  {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0},
    };
UINT numElements = ARRAYSIZE( layout );
    // Create the input layout
hr = device->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
										  pVSBlob->GetBufferSize(), &g_pVertexLayout );
pVSBlob->Release();
if( FAILED( hr ) )
	    return hr;
    // Set the input layout
    pImmediateContext->IASetInputLayout( g_pVertexLayout );
//------------------
// PIXEL SHADER
//------------------
// Compile the pixel shader
ID3DBlob* pPSBlob = NULL;
    hr = CompileShaderFromFile( L"Shader.fx",
	    "PShader",
	    "ps_4_0",
	    &pPSBlob );
//Error handling
    if( FAILED( hr ) )
    {
	    MessageBox( NULL,
				    L"The FX file cannot be compiled.  Please run this executable from the directory that contains the FX file.", L"Error", MB_OK );
	    return hr;
    }
// Create the pixel shader
hr = device->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );
pPSBlob->Release();
    if( FAILED( hr ) )
	    return hr;
//------------------
// CONSTANT BUFFER
//------------------
    D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = 16;
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
//Create Constant Buffer
    device->CreateBuffer(&bd, NULL, &g_pCBuffer);
//Setup Constant Buffer
pImmediateContext->VSSetConstantBuffers(0, 1, &g_pCBuffer);
    if( FAILED( hr ) )
	    return hr;

return hr;
}

void Object::CleanupObject()
{
    if( g_pVertexBuffer ) g_pVertexBuffer->Release();
    if( g_pVertexLayout ) g_pVertexLayout->Release();
    if( g_pVertexShader ) g_pVertexShader->Release();
    if( g_pPixelShader ) g_pPixelShader->Release();
}

Here is also my main loop in main.cpp if you are interested
// Main message loop
    MSG msg = {0};
    while( WM_QUIT != msg.message )
    {
	    if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
	    {
		    TranslateMessage( &msg );
		    DispatchMessage( &msg );
	    }
	    else
	    {
   gfx.clearBackBuffer();	   //Clear Stage
   obj.Render(gfx.getImmediateContext());   //Draw
   obj.InitGraphics(gfx.getDevice(),
	    gfx.getImmediateContext());
   obj.CleanupObject();	   //Cleanup objects
   gfx.present();		 //Present
	    }
    }
    gfx.CleanupDevice();
    return ( int )msg.wParam;


#5 mhagain   Crossbones+   -  Reputation: 7671

Like
0Likes
Like

Posted 05 November 2012 - 04:21 PM

Has your OFFSET type got a fourth float member? Remember that your cbuffer size must be a multiple of 16, UpdateSubresource must update the entire cbuffer in D3D11, so when you're calling UpdateSubresource you're reading from a 12-byte source into a 16-byte destination, you overflow the bounds of the source data and - BOOM!

Simple solution - pad OFFSET to 4 floats (you can leave it as float3 in your shader).

Alternatively, and if you really don't want to do that, use a dynamic cbuffer and Map it with discard instead.

Edited by mhagain, 05 November 2012 - 04:23 PM.

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#6 Xooch   Members   -  Reputation: 179

Like
0Likes
Like

Posted 05 November 2012 - 04:46 PM

Well heres my struct which takes the floats:

struct OFFSET{float X, Y, Z, A;};

I added the A on the end to make it a multiply of 4, but I still get the same problem

edit:

and struct VERTEX taken by UINT stride has always been 4

struct VERTEX{FLOAT X, Y, Z; D3DXCOLOR Color;};

Edited by Xuchilbara, 05 November 2012 - 04:50 PM.


#7 mhagain   Crossbones+   -  Reputation: 7671

Like
0Likes
Like

Posted 05 November 2012 - 05:18 PM

OK, that's fine then.

Your main loop looks very suspect - you're calling Render before you call InitGraphics, meaning that your objects haven't yet been created when you call Render. It's also a baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad idea to create and destroy objects like that every frame. Object creation is expensive so do it once only during startup.

Something like this would be better:

// Main message loop
MSG msg = {0};
obj.InitGraphics(gfx.getDevice(), gfx.getImmediateContext());
while( WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
  TranslateMessage( &msg );
  DispatchMessage( &msg );
}
else
{
  gfx.clearBackBuffer();
  obj.Render(gfx.getImmediateContext());
  gfx.present();
}
}
obj.CleanupObject();
gfx.CleanupDevice();
return ( int )msg.wParam;

It appears that the gentleman thought C++ was extremely difficult and he was overjoyed that the machine was absorbing it; he understood that good C++ is difficult but the best C++ is well-nigh unintelligible.


#8 Xooch   Members   -  Reputation: 179

Like
0Likes
Like

Posted 05 November 2012 - 05:40 PM

Ah you are the man! this has fixed all my problems :) thank you




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