D3D12 ClearRenderTargetView - directx-12

Passing a float array and receiving the warning, "The clear values do not match those passed to resource creation."
1 Works without warning
2 Does not and I tried using the GetFloatArray() method and still receive the warning
Render Target Format is:
clearValue.Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM;
My CColor object:
float RGBA[4];
float* GetFloatArray()
{
return RGBA;
}
The ClearRenderTargetView(s):
// #1
globalObjects->videoDevice->commandList->ClearRenderTargetView(
globalObjects->videoDevice->swapChainRenderTargets[globalObjects->videoDevice->frameIndex]->handle,
CColorCornflowerBlue.GetFloatArray(), 0, nullptr);
// #2
const float c[4] =
{
CColorLovelyPurple.RGBA[0],
CColorLovelyPurple.RGBA[1],
CColorLovelyPurple.RGBA[2],
CColorLovelyPurple.RGBA[3]
};
commandList->ClearRenderTargetView(renderTargets[globalObjects->videoDevice->frameIndex]->handle,
c, 0, nullptr);
Any ideas or if others are having the same problem would be appreciated.

You didn't show us the code that creates the render target view (renderTargets[globalObjects->videoDevice->frameIndex]->handle), but when you create it, the clear value can be set in D3D12_CLEAR_VALUE:
D3D12_CLEAR_VALUE clearValue = {};
clearValue.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
clearValue.Color = c;
Just change the .Color to match the color in the call to commandList->ClearRenderTargetView()

Turns out that I didn't understand a second render target view and was using it incorrectly. For those of you trying to make an overhead it is NOT a second render target but a 2D image instead. My overall goal was an overhead not multiple render targets.
commandList->CopyResource(texture->texture.Get(), renderTargets[globalObjects->videoDevice->frameIndex]->resource.Get());

Related

How to set the color of a face using OpenMesh?

I'm trying to just set the face color of a certain face and my code keeps throwing an error.
The line mesh.set_color(*f_it, clr); is throwing an error (something about a property error). I've tried changing it to mesh.set_color(f_it.handle(), clr); but that throws a dereferencing error.
Am I going about setting the color correctly?
typedef OpenMesh::TriMesh_ArrayKernelT<> myMesh;
myMesh * Mesh;
myMesh mesh;
void computeFaceNormals(myMesh mesh) {
OpenMesh::Vec3f pointA, pointB, pointC;
myMesh::VertexIter vlt, vBegin, vEnd;
myMesh::ConstFaceVertexIter cfvlt;
myMesh::Color clr;
for (myMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); f_it++) {
cfvlt = mesh.cfv_iter(*f_it);
pointA = mesh.point(*cfvlt);
pointB = mesh.point((*cfvlt++));
pointC = mesh.point((*cfvlt++));
clr[0] = 0;
clr[1] = 1;
clr[2] = 0;
mesh.set_color(*f_it, clr);
}
}
The openmesh Mesh (OpenMesh::TriMesh_ArrayKernelT) can work with different properties: vertex-colors, face-colors, vertex-normals and so on. But you need to specify explicitly the properties that you want the Mesh to have.
In your case, what you are missing is a
mesh.request_face_colors();
If you receive the mesh as an argument, you can check whether it already has a color proterty with:
mesh.has_face_colors()
You can also remove properties using:
mesh.release_face_colors();
Read the tutorial for more details. An important note you should consider (from the tutorial) that clarifies the usage of request/has/release:
But, what happens if for example the vertex status property has been
requested twice? Then the first release does nothing, but the second
one will remove it. The standard properties have a reference counter,
which is incremented by one for each request and decremented by one
for each release. If the counter reaches 0 the property will be
removed from memory.

Exception "Texture cannot be null" Direct X

I am coding a 2D Game using DirectX11 and DirectXTK.
I did a class Framework that initializes both the window displayed for the game and initializes DirectX. These initializations work correctly. Then, I decided to draw some backgrounds, etc in the window, but after a while it exits on an exception. I did a try{ ... } catch(){ } block, which tells me that "Texture cannot be null". However, i could not find which texture it is talking about, even by debbugging and checking all the values.
I decided to separate the different elements i was drawing in the window, to see where the problem might come from... So now i have 3 draw methods :
Draw(DWORD &elapsedTime);
DrawBackground(DWORD &elapsedTime);
DrawCharacter(DWORD &elapsedTime);
The Draw(DWORD &elapsedTime) method calls both DrawBackground() and DrawCharacter() methods.
Here is my Draw Method :
void Framework::Draw(DWORD * elapsedTime)
{
// Clearing the Back Buffer
immediateContext->ClearRenderTargetView(renderTargetView, Colors::Aquamarine);
//Clearing the depth buffer to max depth (1.0)
immediateContext->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0); //immediateContext is a ID3D11DeviceContext*
CommonStates states(d3dDevice); //d3dDevice is a ID3D11Device*
sprites.reset(new SpriteBatch(immediateContext));
sprites->Begin(SpriteSortMode_Deferred, states.NonPremultiplied());
DrawBackground1(elapsedTime);
DrawCharacter(elapsedTime);
sprites->End();
//Presenting the back buffer to the front buffer
swapChain->Present(0, 0);
}
By debugging i am almost sure that the exception comes from both DrawBackground() and DrawCharacter(). Indeed, when I comment those in the Draw method, i have no error, but as soon as i put one it sets the exception after displaying what i want during a few seconds.
Here is the method DrawBackground() for example :
void Framework::DrawBackground1(DWORD * elpasedTime)
{
RECT *try1 = new RECT();
try1->bottom = 0; try1->left = 0; try1->right = (int)WIDTH; try1->bottom = (int)HEIGHT;
ID3D11ShaderResourceView * texture2 = nullptr;
ID3D11ShaderResourceView * textureRV = nullptr;
CreateDDSTextureFromFile(d3dDevice, L"../Images/backgrounds/set2_background.dds", nullptr, &textureRV);
CreateDDSTextureFromFile(d3dDevice, L"../Images/backgrounds/set3_tiles.dds", nullptr, &texture2);
sprites->Draw(textureRV, XMFLOAT2(0, 0), try1, Colors::White);
sprites->Draw(texture2, XMFLOAT2(0, 0), try1, Colors::CornflowerBlue);
}
So as soon as i uncomment this method (or any DrawCharacter(), which follows the same steps), the window displays what i expect it to for a few seconds, but then i get the exception "Texture cannot be null". I also noticed that the method DrawCharacter() lets the window displaying what i want longer than the method DrawBackground(), whose texture is way bigger than the character's one.
I'm not sure if this information is useful but i think that maybe this might be linked to the size of the texture ?
Would you notice anything that i did wrong in this code ? Why would a texture be considered null while it does display it for a while ? I've been looking for answers for a few hours now, some help would be amazing please !
Thank you
I noticed that you create two new ID3D11ShaderResourceView every iteration without Release-ing the old ones. You could try by creating the ShaderResourceViews only once and storing them as global variables, or you could try by ->Release() them after the sprites->Draw(...) calls.

DirectX 9 not rendering after adding transforms

so far I got a cube rendered without any transforms (thus it was rendered in an orthographic perspective), and I am working on the previous code to get it into a perspective view, with all the matrices involved. I changed the Flexible Vertex Format so as not to have RHW (thus only having XYZ coordinates and color, tried ARGB and XRGB but I don't think it matters), and I added a function that sets all the matrices.
Debugging
showed that matrices are being created correctly, functions return correctly (as far as I could see), no crashes (DirectX will never complain if something goes wrong, it just doesn't render) and in general, step-by-step debugging shows no paranormal activity.
Existing project (which I modify and eventually prevent from working):
As I advance I also write tutorials of sorts so I can go back and see what I did last time to get it to work, and this time I've kept versions so you can get the code here along with the VS2010 solution, all the DirectX work is done in 3Dheader.h and D3DLoader.h
Changes:
- the custom vertex format FVF_CUSTOMVERTEX has been changed so as not to include RHW, as I understand it has to be removed so as to be computed through the transformations
- In Render() I add a call to the function setMatrices() which does all the matrix and transform work, and is as follows:
void setMatrices()
{
//--------------transformation code----------------//
D3DXMATRIX objectM, translationM, rotationM, projectionM, lookAtM, finalM;
HRESULT hr;
D3DXMatrixIdentity(&objectM);
D3DXMatrixRotationY(&rotationM, D3DX_PI/4);
//D3DXMatrixMultiply(&finalM, &objectM, &rotationM);
D3DXMatrixPerspectiveFovLH(&projectionM,D3DX_PI/4,(float)yRes/xRes, 1, 100);
D3DXVECTOR3 camera;
camera.x = -10;
camera.y = 0;
camera.z = 0;
D3DXVECTOR3 cameraTarget;
cameraTarget.x = 0;
cameraTarget.y = 0;
cameraTarget.z = 0;
D3DXVECTOR3 cameraUp;
cameraUp.x = 0;
cameraUp.y = 1;
cameraUp.z = 0;
D3DXMatrixLookAtLH(&lookAtM,&camera,&cameraTarget, &cameraUp);
hr = pd3dDevice->SetTransform(D3DTS_WORLD, &objectM);
hr = pd3dDevice->SetTransform(D3DTS_PROJECTION, &projectionM);
hr = pd3dDevice->SetTransform(D3DTS_VIEW, &lookAtM);
D3DVIEWPORT9 view_port;
view_port.X=0;
view_port.Y=0;
view_port.Width=xRes;
view_port.Height=yRes;
view_port.MinZ=0.0f;
view_port.MaxZ=1.0f;
pd3dDevice->SetViewport(&view_port);
}
Note of course that some elements may not be needed, placed there just in case during my attempts, this is the code I have currently so we have a common reference.
Thanks in advance for any answers and/or attempts to answer.
In your code (downloaded), xRes and yRes are ints. Due to integer division, yRes/xRes will be zero, because xRes > yRes. You are passing this into the D3DXMatrixPerspextiveFovLH function as the aspect ratio, which will produce an invalid matrix. Instead, cast them to floats first, before doing the division, and pass the result in.

OMSetRenderTargets renders only first provided target

I'm trying to render to multiple ID3D11RenderTargetView simultaneously.
But it seems that only the first target is being rendered:
ID3D11RenderTargetView* targets [ 2 ] = { _backbuffer
, _renderToTextureRTV
};
_devcon->OMSetRenderTargets( 2, targets, nullptr );
Depending on which parameter I specify first in my targets array, will be rendered. The other render target view will not be rendered.
I create my IDXGISwapChain with D3D11_CREATE_DEVICE_DEBUG flag and cannot see any error messages related to this function.
I can reproduce the same problem if I specify nullptr as first targets element. In this case the second element will not be rendered.
But if I specify nullptr as the second element, the first element will be rendered correctly.
Why does OMSetRenderTargets seem to only evaluate the first targets element?
Edit:
What I'm actually trying to achieve is to render to the backbuffer and to a texture simultaneously. I need to render to a texture, as I want to be able to access the pixel values from the CPU.
I want to render to a 16 bit unsigned image, so I use DXGI_FORMAT_R16G16B16A16_UNORM for the texture.
For the backbuffer, I need to use a different format suitable for screen display, so I use DXGI_FORMAT_R16G16B16A16_FLOAT.
For performance reasons, I do not want to element-wise convert between the two and this is the reason why I have two render targets.
Is your pixel shader similar to this one? You need to manually set which render target the pixel shader outputs to:
struct Output
{
float4 target0 : SV_Target0;
float4 target1 : SV_Target1;
};
Output PixelShader(float4 pos : SV_Position)
{
Output output;
output.target0 = float4(1.0, 0, 0, 0); //Output to the first rendertarget
output.target1 = float4(0, 1.0, 0, 0); //Output to the second rendertarget
return output;
}

DirectX using multiple Render Targets as input to each other

I have a fairly simple DirectX 11 framework setup that I want to use for various 2D simulations. I am currently trying to implement the 2D Wave Equation on the GPU. It requires I keep the grid state of the simulation at 2 previous timesteps in order to compute the new one.
How I went about it was this - I have a class called FrameBuffer, which has the following public methods:
bool Initialize(D3DGraphicsObject* graphicsObject, int width, int height);
void BeginRender(float clearRed, float clearGreen, float clearBlue, float clearAlpha) const;
void EndRender() const;
// Return a pointer to the underlying texture resource
const ID3D11ShaderResourceView* GetTextureResource() const;
In my main draw loop I have an array of 3 of these buffers. Every loop I use the textures from the previous 2 buffers as inputs to the next frame buffer and I also draw any user input to change the simulation state. I then draw the result.
int nextStep = simStep+1;
if (nextStep > 2)
nextStep = 0;
mFrameArray[nextStep]->BeginRender(0.0f,0.0f,0.0f,1.0f);
{
mGraphicsObj->SetZBufferState(false);
mQuad->GetRenderer()->RenderBuffers(d3dGraphicsObj->GetDeviceContext());
ID3D11ShaderResourceView* texArray[2] = { mFrameArray[simStep]->GetTextureResource(),
mFrameArray[prevStep]->GetTextureResource() };
result = mWaveShader->Render(d3dGraphicsObj, mQuad->GetRenderer()->GetIndexCount(), texArray);
if (!result)
return false;
// perform any extra input
I_InputSystem *inputSystem = ServiceProvider::Instance().GetInputSystem();
if (inputSystem->IsMouseLeftDown()) {
int x,y;
inputSystem->GetMousePos(x,y);
int width,height;
mGraphicsObj->GetScreenDimensions(width,height);
float xPos = MapValue((float)x,0.0f,(float)width,-1.0f,1.0f);
float yPos = MapValue((float)y,0.0f,(float)height,-1.0f,1.0f);
mColorQuad->mTransform.position = Vector3f(xPos,-yPos,0);
result = mColorQuad->Render(&viewMatrix,&orthoMatrix);
if (!result)
return false;
}
mGraphicsObj->SetZBufferState(true);
}
mFrameArray[nextStep]->EndRender();
prevStep = simStep;
simStep = nextStep;
ID3D11ShaderResourceView* currTexture = mFrameArray[nextStep]->GetTextureResource();
// Render texture to screen
mGraphicsObj->SetZBufferState(false);
mQuad->SetTexture(currTexture);
result = mQuad->Render(&viewMatrix,&orthoMatrix);
if (!result)
return false;
mGraphicsObj->SetZBufferState(true);
The problem is nothing is happening. Whatever I draw appears on the screen(I draw using a small quad) but no part of the simulation is actually ran. I can provide the shader code if required, but I am certain it works since I've implemented this before on the CPU using the same algorithm. I'm just not certain how well D3D render targets work and if I'm just drawing wrong every frame.
EDIT 1:
Here is the code for the begin and end render functions of the frame buffers:
void D3DFrameBuffer::BeginRender(float clearRed, float clearGreen, float clearBlue, float clearAlpha) const {
ID3D11DeviceContext *context = pD3dGraphicsObject->GetDeviceContext();
context->OMSetRenderTargets(1, &(mRenderTargetView._Myptr), pD3dGraphicsObject->GetDepthStencilView());
float color[4];
// Setup the color to clear the buffer to.
color[0] = clearRed;
color[1] = clearGreen;
color[2] = clearBlue;
color[3] = clearAlpha;
// Clear the back buffer.
context->ClearRenderTargetView(mRenderTargetView.get(), color);
// Clear the depth buffer.
context->ClearDepthStencilView(pD3dGraphicsObject->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1.0f, 0);
void D3DFrameBuffer::EndRender() const {
pD3dGraphicsObject->SetBackBufferRenderTarget();
}
Edit 2 Ok, I after I set up the DirectX debug layer I saw that I was using an SRV as a render target while it was still bound to the Pixel stage in out of the shaders. I fixed that by setting shader resources to NULL after I render with the wave shader, but the problem still persists - nothing actually gets ran or updated. I took the render target code from here and slightly modified it, if its any help: http://rastertek.com/dx11tut22.html
Okay, as I understand correct you need a multipass-rendering to texture.
Basiacally you do it like I've described here: link
You creating SRVs with both D3D11_BIND_SHADER_RESOURCE and D3D11_BIND_RENDER_TARGET bind flags.
You ctreating render targets from textures
You set first texture as input (*SetShaderResources()) and second texture as output (OMSetRenderTargets())
You Draw()*
then you bind second texture as input, and third as output
Draw()*
etc.
Additional advices:
If your target GPU capable to write to UAVs from non-compute shaders, you can use it. It is much more simple and less error prone.
If your target GPU suitable, consider using compute shader. It is a pleasure.
Don't forget to enable DirectX debug layer. Sometimes we make obvious errors and debug output can point to them.
Use graphics debugger to review your textures after each draw call.
Edit 1:
As I see, you call BeginRender and OMSetRenderTargets only once, so, all rendering goes into mRenderTargetView. But what you need is to interleave:
SetSRV(texture1);
SetRT(texture2);
Draw();
SetSRV(texture2);
SetRT(texture3);
Draw();
SetSRV(texture3);
SetRT(backBuffer);
Draw();
Also, we don't know what is mRenderTargetView yet.
so, before
result = mColorQuad->Render(&viewMatrix,&orthoMatrix);
somewhere must be OMSetRenderTargets .
Probably, it s better to review your Begin()/End() design, to make resource binding more clearly visible.
Happy coding! =)