Jump to content
  • Advertisement
Sign in to follow this  
Klashnikov Kid

Updating Shader Buffers

This topic is 2970 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Slowly but surely working my through learning DirectX11. Figured I'd start with building some basic GUI elements (2D screen space) to get the hang of using shaders with it. The question at the moment has to do with updating said shader buffers. I can't figure out what I'm doing wrong, it's almost identical to the MSDN tutorial which leads to think it is just my rusty Linear Algebra skills but I would like to run the code by yall real fast. (Was hoping to sharpen up my math once I could get visual feedback.)

Also I've asked this in other threads but does anyone know a good book or site dedicated to DirectX11? Can't really find anything of quality out there.

UIRectangle class - Essentially just a 2D rectangle in screen space.

// Buffer used to update the shader.
struct UIShaderBuffer {
XMMATRIX scale,
rotation,
translation;
};

// Initialize the shader buffer and interface
bool UIRectangle::StartUpShaderBuffer() {
D3D11_BUFFER_DESC _bd;
ZeroMemory(&_bd, sizeof(D3D11_BUFFER_DESC) );
_bd.Usage = D3D11_USAGE_DEFAULT;
_bd.ByteWidth = sizeof(UIShaderBuffer);
_bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
_bd.CPUAccessFlags = 0;
if(FAILED(pDevice->CreateBuffer(&_bd, 0, &pShaderBufferInterface))) {
MessageBox(0, TEXT("UIRectangle: Failed to start up shader buffer interface.\0"), 0, 0);
return false;
} else return true;
}

// Update the buffer. Call before rendering.
void UIRectangle::UpdateShaderBuffer(XMMATRIX &_rScale, XMMATRIX &_rRotation, XMMATRIX &_rTranslation) {
shaderBuffer.scale = _rScale;
shaderBuffer.rotation = _rRotation;
shaderBuffer.translation = _rTranslation;
pDeviceContext->UpdateSubresource(pShaderBufferInterface, 0 , 0, &shaderBuffer, 0, 0);
pDeviceContext->VSSetConstantBuffers(0, 1, &pShaderBufferInterface);
}

// Render
bool UIRectangle::Render() {
UpdateShaderBuffer(
XMMatrixIdentity(),
XMMatrixIdentity(),
XMMatrixTranslation(-0.5f, 1.0f, 1.0f)
);
return Mesh<V_Pos>::Render();
}

template <class V>
bool Mesh<V>::Render() {
pDeviceContext->IASetInputLayout(pVertexLayout);
pDeviceContext->IASetPrimitiveTopology(topologyType);
pDeviceContext->VSSetShader(pVShader, 0, 0);
pDeviceContext->PSSetShader(pPShader, 0, 0);
pDeviceContext->Draw(bufSize, 0);

return true;
}


Here is the shader.

cbuffer ConstantBuffer : register( b0 ) {
matrix scale;
matrix rotation;
matrix translation;
}

float4 VS( float4 _pos : POSITION ) : SV_POSITION {
return mul(_pos, translation);
//return _pos;
}

float4 PS( float4 Pos : SV_POSITION ) : SV_Target {
return float4( 0.3f, 0.0f, 0.0f, 1.0f );
}

As you can see either the buffer is getting invalid information or my understanding that the box should be translated 25% of the screen to the left is incorrect.

Share this post


Link to post
Share on other sites
Advertisement

Also I've asked this in other threads but does anyone know a good book or site dedicated to DirectX11? Can't really find anything of quality out there.



Best DX11 site I've found is www.rastertek.com. Some quality stuff there, if a little brief on explanation. I don't know of any DX11 books, but I do know that Frank Luna (author of the best DX9/DX10 books) has a DX11 version coming out, but not for a good few months and maybe even early next year.

Share this post


Link to post
Share on other sites
By default, shaders expect matrices to be packed in column-major order in constant buffers. XMMATRIX is has a row-major layout in memory, so if you want to put it in a constant buffer you should transpose it (XMMatrixTranspose). Or alternatively, you can compile the shader with D3D10_SHADER_PACK_MATRIX_ROW_MAJOR and then you don't need to transpose. You can also declare the matrices with "row_major" before the type, and the shader will expect row-major data.

As for books, a book I helped out on is coming out in a few weeks: Practical Rendering and Computation with Direct3D 11

Share this post


Link to post
Share on other sites
left or right multiplying a vector vs a matrix can also be used to get the compiler to generate a transposed multiply for you. This can be handy when needing to test if your data needs to be flipped somewhere, as changing the native side is typically a lot more time consuming than reloading an hlsl shader or fx file.


i.e.
float4 somePosition = float4(100,100,500,1);
float4x4 someMatrix = g_LocalToViewWorldProj;

float4 transformedPosition = somePosition * someMatrix;

vs


float4 transformedPosition = someMatrix * somePosition;

Share this post


Link to post
Share on other sites
Oh ok, gotcha! Wasn't aware that the matrices I was using needed to be transposed. Thanks for the tips! Is there any reason why MSDN would prefer XMMatrices over D3DXMatrices?

Anywho, toyed around with transposing them and still can't find my rectangle when I apply a linear transformation, so unless what I'm doing in the shader isn't suppose to yield the result I'm expecting (Shift it 25% of the screen space to the left) than I'm still doing something wrong with the DX11 API.

I noticed I missed the MiscFlags and StructureByteStride for the D3D11_BUFFER_DESC, played around with them but couldn't find any difference in behavior. Also I'm confused about the difference between the ByteWidth and StructureByteStride parameters.

Last but not least, I'm just using a matrix data type in the shader is this different than a float4x4?

Going to post the actual vertex data just in case it could provide any insight.

V_Pos _vertices[] = {
V_Pos(XMFLOAT3( -1.0f, 1.0f, 0.9f )),
V_Pos(XMFLOAT3( 1.0f, 1.0f, 0.9f )),
V_Pos(XMFLOAT3( -1.0f, -1.0f, 0.9f )),
V_Pos(XMFLOAT3( 1.0f, -1.0f, 0.9f ))
};


As for the books, I've actually read and built my own small DX10 rendering engine using Frank Luna's book a year or two ago, however it's all the API nuances and not knowing what was carried over from DX10 (on top of a severely lacking MSDN tutorial) that is really throwing me off. Been waiting for Luna's DX11 book for about a year now, but I'll definitely keep an eye out for Practical Rendering and Computation with Direct3D 11.

Share this post


Link to post
Share on other sites
Well, it's definitely gotta be that the buffers aren't updating. Appended a float to the buffer and used it to alter the rectangle's color in the pixel shader and the rectangle stays black.

I've exhaustively traced over two ways that I've seen MSDN and the D3D11 sample code update their buffer, and both yielded the same result for me. Is there somewhere earlier in my code with initializing the shaders that I need to look at?

And speaking of the two different ways, MSDN simply used a DeviceContext->UpdateSubresource() call to update the shader buffer while the D3D11 sample code utilized DeviceContext->Map() to grab a pointer directly to the buffer. Are there any major differences between the two?

Also MSDN didn't use a D3D11_CPU_ACCESS_WRITE flag in their D3D11_BUFFER_DESC and I'm assuming that's pretty important too.

Share this post


Link to post
Share on other sites
Found a thread with an identical problem that never got resolved (with using the UpdateSubresource() call). http://www.gamedev.n...nstant-buffers/

As recommended in the thread, I enabled DirectX debug output and found this

D3D11: INFO: ID3D11DeviceContext::Draw: Constant Buffer expected at slot 0 of the Pixel Shader unit (with size at least 208 bytes) but none is bound. This is OK, as reads of an unbound Constant Buffer are defined to return 0. It is also posible the developer knows the data will not be used anyway. This is only a problem if the developer actually intended to bind a Constant Buffer here. [ EXECUTION INFO #350: DEVICE_DRAW_CONSTANT_BUFFER_NOT_SET ]

What does this mean? Where else do I need to bind and declare this constant buffer?

My updated relevant code

struct UIShaderBuffer {
XMMATRIX scale,
rotation,
translation;
float temp; // Used to change the rectangle's color.
};

// Initialize the shader buffer and interface
bool UIRectangle::StartUpShaderBuffer() {
UIShaderBuffer _shaderBuffer;
ZeroMemory(&_shaderBuffer, sizeof(UIShaderBuffer));

D3D11_BUFFER_DESC _bd;
ZeroMemory(&_bd, sizeof(D3D11_BUFFER_DESC) );
_bd.Usage = D3D11_USAGE_DYNAMIC;
_bd.ByteWidth = sizeof(UIShaderBuffer);
_bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
_bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
_bd.MiscFlags = 0;
_bd.StructureByteStride = 0;

D3D11_SUBRESOURCE_DATA _subResData;
ZeroMemory(&_subResData, sizeof(D3D11_SUBRESOURCE_DATA));
_subResData.pSysMem = &_shaderBuffer;
_subResData.SysMemPitch = 0;
_subResData.SysMemSlicePitch = 0;

if(FAILED(pDevice->CreateBuffer(&_bd, &_subResData, &pShaderBuffer))) {
MessageBox(0, TEXT("UIRectangle: Failed to bind shader constant buffer.\0"), 0, 0);
return false;
}

pDeviceContext->VSSetConstantBuffers(0, 1, &pShaderBuffer);
pDeviceContext->PSSetConstantBuffers(0, 1, &pShaderBuffer);
return true;
}

// Update the buffer. Call before rendering.
void UIRectangle::UpdateShaderBuffer(XMMATRIX &_rScale, XMMATRIX &_rRotation, XMMATRIX &_rTranslation) {
static UIShaderBuffer _updatedBuffer;
_updatedBuffer.scale = _rScale;
_updatedBuffer.rotation = _rRotation;
_updatedBuffer.translation = _rTranslation;
_updatedBuffer.temp = 1.0f; // Used to affect rectangle color in order to see if buffer is getting updated.

pDeviceContext->UpdateSubresource(pShaderBuffer, 0 , 0, &_updatedBuffer, 0, 0);

/* Alternative method used in D3D11 sample code.
D3D11_MAPPED_SUBRESOURCE mappedResource;
UIShaderBuffer* bufPtr = 0;
if (FAILED(pDeviceContext->Map(pShaderBufferAddr, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource)))
MessageBox(0, TEXT("UIRectangle: Failed to map shader buffer.\0"), 0, 0);
bufPtr = (UIShaderBuffer*) mappedResource.pData;
bufPtr->scale = _rScale;
bufPtr->rotation = _rRotation;
bufPtr->translation = _rTranslation;
bufPtr->temp = pos;
pDeviceContext->Unmap(pShaderBufferAddr, 0);

pDeviceContext->VSSetConstantBuffers(0, 1, &pShaderBufferAddr);
pDeviceContext->PSSetConstantBuffers(0, 1, &pShaderBufferAddr);
*/
}

// Render
bool UIRectangle::Render() {
static XMMATRIX _scale = XMMatrixTranspose(XMMatrixScaling(1.0f, 1.0f, 1.0f)),
_rotation = XMMatrixTranspose(XMMatrixIdentity()),
_translation = XMMatrixTranspose(XMMatrixTranslation(-0.5f, 0.0f, 0.0f));

UpdateShaderBuffer(_scale, _rotation, _translation);
return Mesh<V_Pos>::Render();
}


And the shader...

cbuffer ConstantBuffer : register( b0 ) {
matrix scale;
matrix rotation;
matrix translation;
float temp;
};

float4 VS( float4 _pos : POSITION ) : SV_POSITION {
//return mul(translation, _pos);
return _pos;
}

float4 PS( float4 Pos : SV_POSITION ) : SV_Target {
return float4( temp, temp, temp, 1.0f );
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!