I have a list of 4 verts loaded into a vert buffer, and an index loaded into a index buffer.
The issue I have is that while the LineList rendermode shows a quad just fine (see below) the TriangleList shows nothing (See below)
void BLX::Model::load(std::filesystem::path path, Model* model, ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext)
{
// tmp: just making a quad
float num = 0.5f;
std::vector<BLX::Vertex> vertices = {
BLX::Vertex { DirectX::XMFLOAT3(-num, -num, 0.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 0.5f), }, // 0 = TL
BLX::Vertex { DirectX::XMFLOAT3(num, -num, 0.0f), DirectX::XMFLOAT3(0.0f, 0.5f, 0.0f), }, // 1 = TR
BLX::Vertex { DirectX::XMFLOAT3(num, num, 0.0f), DirectX::XMFLOAT3(0.5f, 0.0f, 0.0f), }, // 2 = BR
BLX::Vertex { DirectX::XMFLOAT3(-num, num, 0.0f), DirectX::XMFLOAT3(0.5f, 0.5f, 0.0f), }, // 3 = BL
};
// line list
//std::vector<unsigned int> indices = { 0, 1, 1, 2, 2, 3, 3, 0 };
// triangle list
std::vector<unsigned int> indices = { 0, 1, 3, 3, 1, 2 };
model->vertexCount = vertices.size();
model->indexCount = indices.size();
// Vertex Buffer
D3D11_BUFFER_DESC vbd = {};
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.Usage = D3D11_USAGE_DEFAULT;
vbd.CPUAccessFlags = 0u;
vbd.MiscFlags = 0u;
vbd.ByteWidth = sizeof(BLX::Vertex) * model->vertexCount;
vbd.StructureByteStride = sizeof(BLX::Vertex);
D3D11_SUBRESOURCE_DATA vsd = {};
vsd.pSysMem = &vertices[0];
vsd.SysMemPitch = 0;
vsd.SysMemSlicePitch = 0;
d3dDevice->CreateBuffer(&vbd, &vsd, &model->vertexBuffer);
/// Index Buffer
D3D11_BUFFER_DESC ibd = {};
ibd.Usage = D3D11_USAGE_DEFAULT;
ibd.ByteWidth = sizeof(unsigned int) * model->indexCount;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA isd = {};
isd.pSysMem = &indices[0];
isd.SysMemPitch = 0;
isd.SysMemSlicePitch = 0;
d3dDevice->CreateBuffer(&ibd, &isd, &model->indexBuffer);
// IA = Input Assembly
// pixel shader
D3DReadFileToBlob(L"PixelShader2.cso", &model->pBlob);
d3dDevice->CreatePixelShader(model->pBlob->GetBufferPointer(), model->pBlob->GetBufferSize(), nullptr, &model->pPixelShader);
// Vertex Shader
D3DReadFileToBlob(L"VertexShader2.cso", &model->pBlob);
d3dDevice->CreateVertexShader(model->pBlob->GetBufferPointer(), model->pBlob->GetBufferSize(), nullptr, &model->pVertexShader);
const D3D11_INPUT_ELEMENT_DESC ied[] =
{
// "Position" correcponds to Vertex Shader Semantic Name
// semantic index
// data type format
// Input slot
// Aligned byte offset
// Input slot class
// Instance data step rate
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{ "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
// needs vertex shader blob
d3dDevice->CreateInputLayout(ied, ARRAYSIZE(ied), model->pBlob->GetBufferPointer(), model->pBlob->GetBufferSize(), &model->pInputLayout);
}
void BLX::Model::render(ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dContext, D3D11_VIEWPORT * vp)
{
const UINT stride = sizeof(Vertex);
const UINT offset[] = { 0u, 0u };
d3dContext->IASetVertexBuffers(0u, 1u, vertexBuffer.GetAddressOf(), &stride, &offset[0]);
d3dContext->IASetIndexBuffer(*indexBuffer.GetAddressOf(), DXGI_FORMAT_R32_UINT, offset[1]);
d3dContext->PSSetShader(pPixelShader.Get(), nullptr, 0u);
d3dContext->VSSetShader(pVertexShader.Get(), nullptr, 0u);
d3dContext->IASetInputLayout(pInputLayout.Get());
d3dContext->RSSetViewports(1u, vp);
//d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D11_PRIMITIVE_TOPOLOGY_LINELIST);
d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
d3dContext->DrawIndexed(indexCount, 0, 0);
}
When using the LineList index and topology:
When using the TriangleList index and topology:
But when I was doing this:
// tmp: just making a quad
float num = 0.5f;
std::vector<BLX::Vertex> vertices = {
BLX::Vertex { DirectX::XMFLOAT3(0.0f, num, 0.0f), DirectX::XMFLOAT3(0.0f, 0.0f, 0.5f), },
BLX::Vertex { DirectX::XMFLOAT3(num, -num, 0.0f), DirectX::XMFLOAT3(0.0f, 0.5f, 0.0f), },
BLX::Vertex { DirectX::XMFLOAT3(-num, -num, 0.0f), DirectX::XMFLOAT3(0.5f, 0.0f, 0.0f), },
};
// triangle list
std::vector<unsigned int> indices = { 0, 1, 2 };
(everything else the exact same) I got this:
Just really curious what I'm not seeing or getting when trying to render two triangles to make up a quad
Your rectangle has indices organized in a clockwise manner, which are culled by the default rasterizer (since you do not specify one it culls clockwise primitives)
Your triangle vertices order was counter clockwise, so the primitive was not culled.
To solve it, two solutions:
Change your indices order :
std::vector<unsigned int> indices = { 0, 3, 1, 3, 2, 1 };
Disable culling in the rasterizer state :
First create one Rasterizer Description
D3D11_RASTERIZER_DESC raster_desc;
raster_desc.FillMode = D3D11_FILL_SOLID;
raster_desc.CullMode= D3D11_CULL_NONE;
raster_desc.FrontCounterClockwise = false;
raster_desc.DepthBias = 0;
raster_desc.DepthBiasClamp= 0.0f;
raster_desc.SlopeScaledDepthBias= 0.0f;
raster_desc.DepthClipEnable= true;
raster_desc.ScissorEnable= false;
raster_desc.MultisampleEnable= false;
raster_desc.AntialiasedLineEnable= false;
Then create a rasterizer state using your device:
ID3D11RasterizerState* raster_state;
HRESULT hr =d3dDevice->CreateRasterizerState(&raster_desc, &raster_state);
Before the draw, assign your rasterizer state to your context:
d3dContext->RSSetState(raster_state);
Your two meshes, triangle and quad, have opposite triangle winding order. Here’s how.
By default, D3D11 uses CullMode=Back and FrontCounterClockwise=FALSE.
This means it only renders front faces, and front face is defined as “when the vertices are counter-clockwise”.
As you see from the above illustration, your triangle indeed has counter-clockwise order, however both triangles of your quad are clockwise, GPU considers them as back faces and skips both.
You have many ways to fix, any of the following will do.
Reorder vertices in vertex buffer.
Flip triangles in index buffer to { 0, 3, 1, 1, 3, 2 }
Change rasterizer state to disable back face culling, CullMode=D3D11_CULL_NONE
Change rasterizer state to switch front face winding direction, FrontCounterClockwise=TRUE
Change matrix passed to vertex shader to include mirroring component, e.g. scale with vector [ -1, 1, 1 ] represents a mirror transform that flips X, this will flip winding order of the whole mesh.
In my code, i am making 2 rectangles,
Rectangle1: Rendering On a Texture.
Rectangle2: Rendering On Back Buffer.
I am trying to do programmable blending,so need to access the destination pixel in pixel shader.
In my code,
I am creating a texture like below:
d3d11Device->CreateTexture2D(&textureDesc, NULL, &renderTargetTextureMap);
After this i am creating Render Target view of the texture.
d3d11Device->CreateRenderTargetView(renderTargetTextureMap, &renderTargetViewDesc, &renderTargetViewMap);
After this i am declaring vertex and pixel shader.
Then in my draw call,
i am performing following thing:
float bgColor[4] = {0.0f, 0.0f,0.0f, 1.0f };
d3d11DevCon->ClearRenderTargetView(renderTargetViewMap, bgColor);
float bgColor2[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
////////////////////////////////////////////////Buffer 1///////////////////////////////////////////////////////////////
//Set the vertex buffer
UINT stride = sizeof(Vertex);
UINT offset = 0;
///////////////////////////////////////////////////////////Buffer 2//////////////////////////////////////////////////////////////////
d3d11DevCon->IASetIndexBuffer(d2dIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
d3d11DevCon->IASetVertexBuffers(0, 1, &triangleVertBuffer, &stride, &offset);
////Draw the triangle
d3d11DevCon->DrawIndexed(6, 0, 0);
I assume that since i have set my render target view as renderTargetViewMap, so my draw call will render to texture only.
Now i am rendering to my backbuffer:
////////////////////////////////////////////
d3d11DevCon->OMSetRenderTargets(1, &renderTargetView, NULL);
d3d11DevCon->PSSetShaderResources(0, 1, &shaderResourceViewMap);
//d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor2);
d3d11DevCon->IASetIndexBuffer(d2dIndexBuffer2, DXGI_FORMAT_R32_UINT, 0);
d3d11DevCon->IASetVertexBuffers(0, 1, &triangleVertBuffer2, &stride, &offset);
////Draw the triangle
d3d11DevCon->DrawIndexed(6, 0, 0);
//Present the backbuffer to the screen
SwapChain->Present(0, 0);
So, in this way my rendering is happening.
Issue Face:
In my pixel shader,
VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR)
{
VS_OUTPUT output;
output.Pos = inPos;
output.Color = inColor;
return output;
}
float4 PS(VS_OUTPUT input) : SV_TARGET
{
float2 temp;
temp = input.Pos;
float4 diffuse = ObjTexture.Sample(ObjSamplerState,0.5+0.5*temp);
return input.Color + diffuse;
}
Here the diffuse is comming out to be equal to my bgcolor which i have set when rendering to texture
float bgColor[4] = {0.0f, 0.0f,0.0f, 1.0f };
d3d11DevCon->ClearRenderTargetView(renderTargetViewMap, bgColor);
I have also drawn a rectangle on it, but those pixels i am not able to access.
How can i access the pixel of rectangle that i have drawn on rendering to texture.
This is Issue Image
Desired Result
Shader File: Effect.fx
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
Texture2D ObjTexture;
SamplerState ObjSamplerState;
VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR)
{
VS_OUTPUT output;
output.Pos = inPos;
output.Color = inColor;
return output;
}
float4 PS(VS_OUTPUT input) : SV_TARGET
{
float2 temp;
temp = input.Pos;
float4 diffuse = ObjTexture.Sample(ObjSamplerState,0.5+0.5*temp);
return input.Color + diffuse;
}
Edit - 1:
With my latest change in code, i am able to blend my rectangle 2 with rectangle 1, but one issue i am facing is that when i blend then major part of my rectangle 2 is changes to yellow (red + green) on edges only i am able to see the actual green color.
Modified code:
main.cpp
//Include and link appropriate libraries and headers//
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")
#pragma comment(lib, "d3dx10.lib")
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <d3dx10.h>
#include <xnamath.h>
//Global Declarations - Interfaces//
IDXGISwapChain* SwapChain;
ID3D11Device* d3d11Device;
ID3D11DeviceContext* d3d11DevCon;
ID3D11RenderTargetView* renderTargetView;
ID3D11Buffer* triangleVertBuffer;
ID3D11Buffer* triangleVertBuffer2;
ID3D11VertexShader* VS;
ID3D11PixelShader* PS;
ID3D10Blob* VS_Buffer;
ID3D10Blob* PS_Buffer;
ID3D11InputLayout* vertLayout;
XMMATRIX mapView;
XMMATRIX mapProjection;
XMVECTOR DefaultForward = XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
//Global Declarations - Others//
LPCTSTR WndClassName = L"firstwindow";
HWND hwnd = NULL;
HRESULT hr;
const int Width = 800;
const int Height = 600;
bool InitializeDirect3d11App(HINSTANCE hInstance)
{
//Describe our Buffer
DXGI_MODE_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
bufferDesc.Width = Width;
bufferDesc.Height = Height;
bufferDesc.RefreshRate.Numerator = 60;
bufferDesc.RefreshRate.Denominator = 1;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//Describe our SwapChain
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = hwnd;
swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
//Create our SwapChain
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, NULL, &d3d11DevCon);
//Create our BackBuffer
ID3D11Texture2D* BackBuffer;
hr = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);
//Create our Render Target
hr = d3d11Device->CreateRenderTargetView(BackBuffer, NULL, &renderTargetView);
BackBuffer->Release();
////////////////////////////////////////////////////////////////////////EXPERIMENT AREA//////////////////////////////////////////////////////////////////////////////////////
ZeroMemory(&textureDesc, sizeof(textureDesc));
// Setup the texture description.
// We will have our map be a square
// We will need to have this texture bound as a render target AND a shader resource
textureDesc.Width = Width/ 3.9729999999999999999999999999999;
textureDesc.Height = Height/3.9729999999999999999999999999999;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
d3d11Device->CreateTexture2D(&textureDesc, NULL, &renderTargetTextureMap);
// Setup the description of the render target view.
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
// Create the render target view.
d3d11Device->CreateRenderTargetView(renderTargetTextureMap, &renderTargetViewDesc, &renderTargetViewMap);
/////////////////////// Map's Shader Resource View
// Setup the description of the shader resource view.
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
// Create the shader resource view.
d3d11Device->CreateShaderResourceView(renderTargetTextureMap, &shaderResourceViewDesc, &shaderResourceViewMap);
d3d11DevCon->OMSetRenderTargets(1, &renderTargetViewMap, NULL);
d3d11DevCon->PSSetShaderResources(0, 1, &shaderResourceViewMap);
return true;
}
void CleanUp()
{
//Release the COM Objects we created
SwapChain->Release();
d3d11Device->Release();
d3d11DevCon->Release();
renderTargetView->Release();
triangleVertBuffer->Release();
VS->Release();
PS->Release();
VS_Buffer->Release();
PS_Buffer->Release();
vertLayout->Release();
}
bool InitScene()
{
//Compile Shaders from shader file
hr = D3DX11CompileFromFile(L"Effect.fx", 0, 0, "VS", "vs_5_0", 0, 0, 0, &VS_Buffer, 0, 0);
hr = D3DX11CompileFromFile(L"Effect.fx", 0, 0, "PS", "ps_5_0", 0, 0, 0, &PS_Buffer, 0, 0);
//Create the Shader Objects
hr = d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS);
hr = d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS);
//Set Vertex and Pixel Shaders
d3d11DevCon->VSSetShader(VS, 0, 0);
d3d11DevCon->PSSetShader(PS, 0, 0);
//Create the Input Layout
hr = d3d11Device->CreateInputLayout(layout, numElements, VS_Buffer->GetBufferPointer(),
VS_Buffer->GetBufferSize(), &vertLayout);
//Set the Input Layout
d3d11DevCon->IASetInputLayout(vertLayout);
//Set Primitive Topology
d3d11DevCon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//Create the Viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = 800;
viewport.Height = 600;
//Set the Viewport
d3d11DevCon->RSSetViewports(1, &viewport);
////////////////***********************First Texture Vertex Buffer *******************************/////////////////////////////
//Create the vertex buffer
Vertex v[] =
{
Vertex(-0.5f, -0.5f, 0.0f, 1.0f,0.0f,0.0f, 1.0f),
Vertex(-0.5f, 0.5f, 0.0f, 1.0f,0.0f,0.0f, 1.0f),
Vertex(0.5f, 0.5f, 0.0f, 1.0f, 0.0f,0.0f, 1.0f),
Vertex(0.5f, -0.5f, 0.0f, 1.0f,0.0f, 0.0f, 1.0f),
};
DWORD indices[] = {
// Front Face
0, 1, 3,
1, 2, 3,
};
D3D11_BUFFER_DESC indexBufferDesc;
ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc));
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(DWORD) * 2 * 3;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices;
d3d11Device->CreateBuffer(&indexBufferDesc, &iinitData, &d2dIndexBuffer);
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(Vertex) * 4;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
vertexBufferData.pSysMem = v;
hr = d3d11Device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &triangleVertBuffer);
////////////////////////////////////////////////////// Second Vertex.
Vertex v2[] = {
// positions // colors // texture coords
Vertex(1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // top right
Vertex(1.0f,0.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // bottom right
Vertex(0.0f,0.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // bottom left
Vertex(0.0f, 1.0, 0.0f,0.0f, 1.0f,0.0f,1.0f) // top left
};
DWORD indices2[] = {
// Front Face
0, 1, 2,
0, 2, 3,
};
D3D11_BUFFER_DESC indexBufferDesc2;
ZeroMemory(&indexBufferDesc2, sizeof(indexBufferDesc2));
indexBufferDesc2.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc2.ByteWidth = sizeof(DWORD) * 2 * 3;
indexBufferDesc2.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc2.CPUAccessFlags = 0;
indexBufferDesc2.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData2;
iinitData2.pSysMem = indices2;
d3d11Device->CreateBuffer(&indexBufferDesc2, &iinitData2, &d2dIndexBuffer2);
D3D11_BUFFER_DESC vertexBufferDesc2;
ZeroMemory(&vertexBufferDesc2, sizeof(vertexBufferDesc2));
vertexBufferDesc2.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc2.ByteWidth = sizeof(Vertex) * 4;
vertexBufferDesc2.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc2.CPUAccessFlags = 0;
vertexBufferDesc2.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData2;
ZeroMemory(&vertexBufferData2, sizeof(vertexBufferData2));
vertexBufferData2.pSysMem = v2;
hr = d3d11Device->CreateBuffer(&vertexBufferDesc2, &vertexBufferData2, &triangleVertBuffer2);
UINT stride = sizeof(Vertex);
UINT offset = 0;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return true;
}
Shader File:
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
Texture2D ObjTexture;
SamplerState ObjSamplerState;
VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR)
{
VS_OUTPUT output;
output.Pos = inPos;
output.Color = inColor;
return output;
}
float4 PS(VS_OUTPUT input) : SV_TARGET
{
float2 temp;
temp = input.Pos;
float4 diffuse = ObjTexture.Sample(ObjSamplerState,0.5*temp);
return input.Color + diffuse ;
}
return DefWindowProc(hwnd,
msg,
wParam,
lParam);
}
Edit 3:
My vertex Structure:
struct Vertex //Overloaded Vertex Structure
{
Vertex() {}
Vertex(float x, float y, float z,
float cr, float cg, float cb, float ca)
: pos(x, y, z), color(cr, cg, cb, ca) {}
XMFLOAT3 pos;
XMFLOAT4 color;
};
Input description:
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 },
};
I think so issue is when i pass my texture and read it in diffuse in pixel shader, then mapping of my texture on back buffer is not same and hence i am only finding red color from 2nd scan line and hence resultant zero is produced..?
Edit 3:
My initialization code:
struct Vertex //Overloaded Vertex Structure
{
Vertex() {}
Vertex(float x, float y, float z,
float cr, float cg, float cb, float ca)
: pos(x, y, z), color(cr, cg, cb, ca) {}
XMFLOAT3 pos;
XMFLOAT4 color;
};
ID3D11Texture2D* renderTargetTextureMap;
ID3D11RenderTargetView* renderTargetViewMap;
ID3D11ShaderResourceView* shaderResourceViewMap;
ID3D11SamplerState* CubesTexSamplerState;
ID3D11Buffer *d2dIndexBuffer;
ID3D11Buffer *d2dIndexBuffer2;
D3D11_TEXTURE2D_DESC textureDesc;
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;
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);
bool InitializeDirect3d11App(HINSTANCE hInstance)
{
//Describe our Buffer
DXGI_MODE_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
bufferDesc.Width = Width;
bufferDesc.Height = Height;
bufferDesc.RefreshRate.Numerator = 60;
bufferDesc.RefreshRate.Denominator = 1;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
//Describe our SwapChain
DXGI_SWAP_CHAIN_DESC swapChainDesc;
ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = hwnd;
swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
//Create our SwapChain
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL,
D3D11_SDK_VERSION, &swapChainDesc, &SwapChain, &d3d11Device, NULL, &d3d11DevCon);
//Create our BackBuffer
ID3D11Texture2D* BackBuffer;
hr = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);
//Create our Render Target
hr = d3d11Device->CreateRenderTargetView(BackBuffer, NULL, &renderTargetView);
BackBuffer->Release();
////////////////////////////////////////////////////////////////////////EXPERIMENT AREA//////////////////////////////////////////////////////////////////////////////////////
ZeroMemory(&textureDesc, sizeof(textureDesc));
// Setup the texture description.
// We will have our map be a square
// We will need to have this texture bound as a render target AND a shader resource
textureDesc.Width = Width/2;
textureDesc.Height = Height/2;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;
d3d11Device->CreateTexture2D(&textureDesc, NULL, &renderTargetTextureMap);
// Setup the description of the render target view.
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
// Create the render target view.
d3d11Device->CreateRenderTargetView(renderTargetTextureMap, &renderTargetViewDesc, &renderTargetView);
/////////////////////// Map's Shader Resource View
// Setup the description of the shader resource view.
shaderResourceViewDesc.Format = textureDesc.Format;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;
// Create the shader resource view.
d3d11Device->CreateShaderResourceView(renderTargetTextureMap, &shaderResourceViewDesc, &shaderResourceViewMap);
//d3d11DevCon->OMSetRenderTargets(1, &renderTargetViewMap, NULL);
//d3d11DevCon->PSSetShaderResources(0, 1, &shaderResourceViewMap);
return true;
}
void CleanUp()
{
//Release the COM Objects we created
SwapChain->Release();
d3d11Device->Release();
d3d11DevCon->Release();
renderTargetView->Release();
triangleVertBuffer->Release();
VS->Release();
PS->Release();
VS_Buffer->Release();
PS_Buffer->Release();
vertLayout->Release();
}
bool InitScene()
{
//Compile Shaders from shader file
hr = D3DX11CompileFromFile(L"Effect.fx", 0, 0, "VS", "vs_5_0", 0, 0, 0, &VS_Buffer, 0, 0);
hr = D3DX11CompileFromFile(L"Effect.fx", 0, 0, "PS", "ps_5_0", 0, 0, 0, &PS_Buffer, 0, 0);
//Create the Shader Objects
hr = d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS);
hr = d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS);
//Set Vertex and Pixel Shaders
d3d11DevCon->VSSetShader(VS, 0, 0);
d3d11DevCon->PSSetShader(PS, 0, 0);
//Create the Input Layout
hr = d3d11Device->CreateInputLayout(layout, numElements, VS_Buffer->GetBufferPointer(),
VS_Buffer->GetBufferSize(), &vertLayout);
//Set the Input Layout
d3d11DevCon->IASetInputLayout(vertLayout);
//Set Primitive Topology
d3d11DevCon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//Create the Viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = 800;
viewport.Height = 600;
//Set the Viewport
d3d11DevCon->RSSetViewports(1, &viewport);
////////////////***********************First Texture Vertex Buffer *******************************/////////////////////////////
//Create the vertex buffer
Vertex v[] =
{
Vertex(-0.35f, -0.35f, 0.0f, 1.0f,0.0f,0.0f, 1.0f),
Vertex(-0.35f, 0.35f, 0.0f, 1.0f,0.0f,0.0f, 1.0f),
Vertex(0.35f, 0.35f, 0.0f, 1.0f, 0.0f,0.0f, 1.0f),
Vertex(0.35f, -0.35f, 0.0f, 1.0f,0.0f, 0.0f, 1.0f),
};
DWORD indices[] = {
// Front Face
0, 1, 3,
1, 2, 3,
};
D3D11_BUFFER_DESC indexBufferDesc;
ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc));
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(DWORD) * 2 * 3;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices;
d3d11Device->CreateBuffer(&indexBufferDesc, &iinitData, &d2dIndexBuffer);
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(Vertex) * 4;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
vertexBufferData.pSysMem = v;
hr = d3d11Device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &triangleVertBuffer);
////////////////////////////////////////////////////// Second Vertex.
Vertex v2[] = {
// positions // colors // texture coords
Vertex(1.0f, 1.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // top right
Vertex(1.0f,0.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // bottom right
Vertex(0.0f,0.0f, 0.0f,0.0f,1.0f,0.0f,1.0f), // bottom left
Vertex(0.0f, 1.0, 0.0f,0.0f, 1.0f,0.0f,1.0f) // top left
};
DWORD indices2[] = {
// Front Face
0, 1, 2,
0, 2, 3,
};
D3D11_BUFFER_DESC indexBufferDesc2;
ZeroMemory(&indexBufferDesc2, sizeof(indexBufferDesc2));
indexBufferDesc2.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc2.ByteWidth = sizeof(DWORD) * 2 * 3;
indexBufferDesc2.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc2.CPUAccessFlags = 0;
indexBufferDesc2.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData2;
iinitData2.pSysMem = indices2;
d3d11Device->CreateBuffer(&indexBufferDesc2, &iinitData2, &d2dIndexBuffer2);
D3D11_BUFFER_DESC vertexBufferDesc2;
ZeroMemory(&vertexBufferDesc2, sizeof(vertexBufferDesc2));
vertexBufferDesc2.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc2.ByteWidth = sizeof(Vertex) * 4;
vertexBufferDesc2.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc2.CPUAccessFlags = 0;
vertexBufferDesc2.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData2;
ZeroMemory(&vertexBufferData2, sizeof(vertexBufferData2));
vertexBufferData2.pSysMem = v2;
hr = d3d11Device->CreateBuffer(&vertexBufferDesc2, &vertexBufferData2, &triangleVertBuffer2);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
return true;
}
Edit 4:
Added draw scene code:
void DrawScene()
{
//Set the vertex buffer
UINT stride = sizeof(Vertex);
UINT offset = 0;
///////////////////////////////////////////////////////////Buffer 2//////////////////////////////////////////////////////////////////
d3d11DevCon->IASetIndexBuffer(d2dIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
d3d11DevCon->IASetVertexBuffers(0, 1, &triangleVertBuffer, &stride, &offset);
////Draw the triangle
d3d11DevCon->DrawIndexed(6, 0, 0);
d3d11DevCon->OMSetRenderTargets(1, &renderTargetView, NULL);
////////////////////////////////////////////
d3d11DevCon->PSSetShaderResources(0, 1, &shaderResourceViewMap);
d3d11DevCon->IASetIndexBuffer(d2dIndexBuffer2, DXGI_FORMAT_R32_UINT, 0);
d3d11DevCon->IASetVertexBuffers(0, 1, &triangleVertBuffer2, &stride, &offset);
////Draw the triangle
d3d11DevCon->DrawIndexed(6, 0, 0);
//Present the backbuffer to the screen
SwapChain->Present(0, 0);
}
In order to calculate correct texture coordinates from the vertex Position, you need to:
1.Create the render target texture with Width and Height (not the halves):
textureDesc.Width = Width; // /2; // Do not use half width
textureDesc.Height = Height; // /2; // Do not use half height
2.Divide the position to a float2(1 / Width, 1 / Height) in your pixel shader, like this:
float2 tex = input.Pos * float2(1.0f / 800.0f, 1.0f / 600.0f);
float4 diffuse = ObjTexture.Sample(ObjSamplerState, tex);
return input.Color + diffuse;
Shader Code
struct Light
{
float3 dir;
float4 ambient;
float4 diffuse;
};
cbuffer cbPerFrame
{
Light light;
};
cbuffer cbPerObject
{
float4x4 WVP;
float4x4 World;
};
Texture2D ObjTexture;
SamplerState ObjSamplerState;
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float2 TexCoord : TEXCOORD;
float3 normal : NORMAL;
float4 InstancePos : INSTANCEPOS;
};
VS_OUTPUT VS(float4 inPos : POSITION, float2 inTexCoord : TEXCOORD, float3 normal : NORMAL , float4 InstancePos : INSTANCEPOS;)
{
VS_OUTPUT output;
output.Pos.x+=InstancePos.x;
output.Pos.y+=InstancePos.y;
output.Pos.z+=InstancePos.z;
output.Pos = mul(inPos, WVP);
output.TexCoord = inTexCoord;
output.normal = mul(normal, World);
output.normal = normalize(output.normal);
return output;
}
float4 PS(VS_OUTPUT input) : SV_TARGET
{
input.normal = normalize(input.normal);
float4 diffuse = ObjTexture.Sample( ObjSamplerState, input.TexCoord );
float3 finalColor;
finalColor = diffuse * light.ambient;
finalColor += saturate(dot(light.dir, input.normal) * light.diffuse * diffuse);
clip(diffuse.a - .10);
return float4(finalColor, diffuse.a);
}
//// creation
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD0", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 20, D3D11_INPUT_PER_VERTEX_DATA, 0},
{ "INSTANCEPOS", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1}
};
hr = D3DX11CompileFromFile(L"Effects.fx", 0, 0, "VS", "vs_4_0", 0, 0, 0, &VS_Buffer, 0, 0);
hr = D3DX11CompileFromFile(L"Effects.fx", 0, 0, "PS", "ps_4_0", 0, 0, 0, &PS_Buffer, 0, 0);
//Create the Shader Objects
hr = d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS);
hr = d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS);
//===============Create the Input Layout==================================
hr = d3d11Device->CreateInputLayout( layout, numElements, VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), &vertLayout );
CreateInputLayout is returning E_INVALIDARG. I have tried but it's not working. I added the D3D11_INPUT_PER_INSTANCE_DATA flag since I'm working with instances, but it works fine when I remove that.
Are you sure the shader compile and the vs_buffer is not nil ? That semicolon should give you a compilation error : : INSTANCEPOS;)
The layout setup does not exhibit invalid values that should fail so it is the shader that is not here. Also your texcoord offset should be 12 and not 16 considering the position format, you rendering would be bogus but that technically valid.
I'm a new D3D programmer.
When I tried to render a model, I got a strange problem.!
you can see the picture, some part of the model always in front of the others.
the model vertex only contains the following data
{
float x, y, z;
float r, g, b;
float u, v;
}
I tried to render it in opengl and webgl ( http://nalol.azurewebsites.net/ ), it works well. but in D3D11, I got this strange problem.
I tried Google and find something about depth, but i don't know how to deal with it.
the following are some part of my code:
HLSL file
struct vout
{
float4 position : SV_POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD;
};
vout vshader(float3 position : POSITION, float3 normals : NORMAL, float2 texcoords : TEXCOORD)
{
vout output;
output.position = float4(position, 1);
output.normal = normals ;
output.texcoord = texcoords;
return output;
}
Texture2D shaderTexture;
SamplerState SampleType;
float3 pshader(float3 position : POSITION, float3 normals : NORMAL, float2 texcoords : TEXCOORD) : SV_TARGET
{
return shaderTexture.Sample(SampleType, texcoords);
}
vertex struct
struct lol_skn_vertex {
float position[3];
char bone_index[4]; // for bones and animation, not used here
float bone_weights[4]; // for bones and animation, not used here
float normals[3];
float texcoords[2];
};
input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"NORMAL", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 44, D3D11_INPUT_PER_VERTEX_DATA, 0},
};
render function
void RenderFrame(void)
{
FLOAT ColorRGBA[4] = {0.0f, 0.2f, 0.4f, 1.0f};
d3d11_device_context->ClearRenderTargetView(d3d11_view_rt_backbuffer, ColorRGBA);
d3d11_device_context->ClearDepthStencilView(d3d11_view_ds,D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL,1.f,0);
update();
UINT stride = sizeof(lol_skn_vertex);
UINT offset = 0;
d3d11_device_context->IASetVertexBuffers(0, 1, &vertex_buffer, &stride, &offset);
d3d11_device_context->IASetIndexBuffer(index_buffer, DXGI_FORMAT_R16_UINT, 0);
d3d11_device_context->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
d3d11_device_context->DrawIndexed(skn.num_indices, 0, 0);
// switch the back buffer and the front buffer
dxgi_swapchain->Present(0, 0);
}
buffer update function
void update() {
// copy the vertices into the buffer
D3D11_MAPPED_SUBRESOURCE ms;
d3d11_device_context->Map(vertex_buffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, skn_vertex_buffer, sizeof(lol_skn_vertex) * skn.num_vertices); // copy the data
// unmap the buffer
SYSTEMTIME SystemTime;
GetSystemTime(&SystemTime);
float angle = (float)SystemTime.wMilliseconds/1000+SystemTime.wSecond;
D3DXMATRIX x;
D3DXMatrixRotationY(&x, angle);
D3DXVec4TransformArray((D3DXVECTOR4 *)ms.pData, sizeof(lol_skn_vertex), (D3DXVECTOR4 *)ms.pData, sizeof(lol_skn_vertex), &x, skn.num_vertices);
// use D3DXVECTOR4 for Transform
d3d11_device_context->Unmap(vertex_buffer, NULL);
}
At last I solved the problem.
I make 2 very stupid mistake.
first: in "input layout object", i use DXGI_FORMAT_R32G32_FLOAT for position, which only contain x and y. so the shader always get 0 on z.
second: my model data is not normalized, which ranged from -50 to 50, so i use D3D11_RASTERIZER_DESC to disable DepthClip and I forgot about it.
Fix this 2 problems and everything works.
And great thank to Gnietschow :)