Point to quad expansion with Geometry Shader - c++

I am new to the geometry shader, so I am trying to make a geometry shader that will take a point and create a quad with texture coordinates, just as an example to see how the geometry shader works. Here is the code I have written:
Texture2D txDiffuse : register( t0 );
SamplerState samAnisotropic
{
Filter = ANISOTROPIC;
MaxAnisotropy = 4;
};
cbuffer cbFixed
{
//
// Compute texture coordinates to stretch texture over quad.
//
float2 gTexC[4] =
{
float2(0.0f, 1.0f),
float2(0.0f, 0.0f),
float2(1.0f, 1.0f),
float2(1.0f, 0.0f)
};
};
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
}
struct VS_INPUT
{
float3 Pos : POSITION;
};
struct VertexOut
{
float3 Pos : POSITION;
};
struct GeoOut
{
float4 PosH : SV_POSITION;
float2 Tex : TEXCOORD;
uint PrimID : SV_PrimitiveID;
};
VertexOut VS( VS_INPUT input )
{
VertexOut output;
output.Pos = input.Pos;
return output;
}
[maxvertexcount(4)]
void GS(point VertexOut gin[1], uint primID : SV_PrimitiveID, inout TriangleStream<GeoOut> tristream)
{
float4 v[4];
v[0] = float4(gin[0].Pos + float3(1.0f, -1.0f, 0.0f), 1.0f);
v[1] = float4(gin[0].Pos + float3(1.0f, 1.0f, 0.0f), 1.0f);
v[2] = float4(gin[0].Pos + float3(-1.0f, -1.0f, 0.0f), 1.0f);
v[3] = float4(gin[0].Pos + float3(-1.0f, 1.0f, 0.0f), 1.0f);
GeoOut gout;
[unroll]
for (int i = 0; i < 4; i++)
{
gout.PosH = mul(v[i], World);
gout.PosH = mul(v[i], View);
gout.PosH = mul(v[i], Projection);
gout.Tex = gTexC[i];
gout.PrimID = primID;
tristream.Append(gout);
}
}
float4 PS( GeoOut input) : SV_Target
{
//return txDiffuse.Sample( samAnisotropic, input.Tex );
return float4( 1.0f, 1.0f, 1.0f, 1.0f );
}
When I compile this code, I get a blank screen. At first I thought it may be a texture problem, so I tried having the pixel shader output white, but it did not help. Next I thought it may not show because of the way the triangle is wound, so I disabled back face culling, but it still did not help. I'm not sure what to try next. Any ideas on the problem?

I have not ever worked with geometry shaders, but I think the way you're calculating gout.PosH is wrong. It should be
float4 p = mul(v[i], World);
p = mul(p, View);
p = mul(p, Projection);
gout.PosH = p;
See where you went wrong? Hope this helps.

Related

Trouble with constant buffers

im trying to use constant buffers in d3d11 but turns out that when the shader multiplies the pos vector with the matrix it doesnt return anything and i get a black screen,i have tried everything that i found on tutorials but i had nothing,here is the code:
D3D11_BUFFER_DESC udesc;
ZeroMemory(&udesc,sizeof(D3D11_BUFFER_DESC));
udesc.Usage = D3D11_USAGE_DEFAULT;
udesc.CPUAccessFlags = 0;
udesc.ByteWidth = sizeof(uniformsperobj);
udesc.MiscFlags = 0;
udesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
hr = dispositivo->CreateBuffer(&udesc,NULL,&uniformbuffer);
//draw frame function//
model = XMMatrixIdentity();
campos = XMVectorSet(0.0f, 0.0f, -0.5f, 0.0f);
camtarget = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
camup = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
view = XMMatrixLookAtLH(posdecam, objdecam, arrdecam);
proyection = XMMatrixPerspectiveFovLH(0.4f * 3.14f, (float)WINDOW_WIDTH /WINDOW_HEIGHT, 1.0, 1000.0f);
XMMATRIX MVP = model*view*proyection;
upo.MVP = XMMatrixTranspose(MVP);
context->UpdateSubresource(uniformbuffer,0,NULL,&upo,0,0);
context->VSSetConstantBuffers(0,1,&uniformbuffer)
/*
********************************shaders.fx***********************************************
*/
cbuffer uniformesporobjeto
{
float4x4 MVP;
};
struct vertex
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
vertex vshader(float4 position : POSITION, float4 color : COLOR)
{
vertex output;
output.Pos = mul(position, MVP);
output.Color = color;
return output;
}
float4 pshader(vertex input) : SV_TARGET
{
return input.Color;
}
sorry if i posted too much code but the problem is that i dont really know were the error is because im stupid

Direct3D11 wrong vertex transformations in vertex shader

I'm trying to run a practice of D3D 11 rendering system to load and render FBX files but I have a problem transforming vertex in vertex shader.
I don't suppose what is wrong, in Visual Studio Graphics Debugger I can see the mesh passed to pipeline is OK in the input assembler stage but after vertex shader transformations all breaks out and render go wrong, if someone can tell me what's go wrong I'll appreciate the info.
View of the Input Assembler Stage
View of the Vertex Shader Output
This is the Vertex Shader code
cbuffer MatrixBuffer
{
matrix worldMatrix;
matrix viewMatrix;
matrix projectionMatrix;
};
struct VertexInputType
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD;
};
struct PixelInputType
{
float4 position : SV_POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD;
};
PixelInputType TextureVertexShader(VertexInputType input)
{
PixelInputType output;
output.position = mul(input.position, worldMatrix);
output.position = mul(output.position, viewMatrix);
output.position = mul(output.position, projectionMatrix);
output.normal = input.normal;
output.uv = input.uv;
return output;
}
And this is the code of matrix initialization
float lFieldOfView = 3.141592f * 0.4f;
float lScreenAspect = static_cast<float>(width_) / static_cast<float>(height_);
DirectX::XMMATRIX lProjection = MatrixDirectX::XMMatrixPerspectiveFovLHlFieldOfView, lScreenAspect, 1.0f, 10000.0f);
DirectX::XMStoreFloat4x4(&lMatrixBuffer.projectionMatrix, lProjectionMatrix);
DirectX::XMMATRIX lWorldMatrix = DirectX::XMMatrixIdentity();
DirectX::XMStoreFloat4x4(&lMatrixBuffer.worldMatrix, lWorldMatrix);
DirectX::XMFLOAT3 lookAtPos(0.0f, 0.0f, 0.0f);
DirectX::XMFLOAT3 eyePos(0.0f, 0.0f, -50.0f);
DirectX::XMFLOAT3 upDir(0.0f, 1.0f, 0.0f);
DirectX::FXMVECTOR lLookAtPos = DirectX::XMLoadFloat3(&lookAtPos);
DirectX::FXMVECTOR lEyePos = DirectX::XMLoadFloat3(&eyePos);
DirectX::FXMVECTOR lUpDir = DirectX::XMLoadFloat3(&upDir);
DirectX::XMMATRIX lViewMatrix = DirectX::XMMatrixLookAtLH(lEyePos, lLookAtPos, lUpDir);
DirectX::XMStoreFloat4x4(&lMatrixBuffer.viewMatrix, lViewMatrix);
D3D11_BUFFER_DESC lBufferDesc = { 0 };
lBufferDesc.ByteWidth = sizeof(MatrixBufferType);
lBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
lBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
D3D11_SUBRESOURCE_DATA lMatrixBufferData;
lMatrixBufferData.pSysMem = &lMatrixBuffer;
hResult = D3DDevice_->CreateBuffer(&lBufferDesc, &lMatrixBufferData, &D3DMatrixBuffer_);
From the comment it looks like the issue actually might be a matrix row-major/column-major difference. The original HLSL code would probably work if the matrices would be transposed on the CPU side.

Direct3D11: Rendering 2D in 3D scene: how to make 2D objects not move on Viewport when camera changes position?

Images with examples of the problem: http://imgur.com/gallery/vmMyk
Hi,
I need some help with rendering 2D objects in 3D scene with 3D camera. I think I managed to solve 2D coordinates with LH world coordinates. However, my rendered 2D objects are in a correct place, only when camera is at [0.0f, 0.0f, 0.0f] coordinates. In every other position, the location of 2D objects on scene is malformed. I think my matrices are screwed up, but don't know where to look further. I'd appreciate good ideas, please comment if something's missing for you, I'll edit the main post to provide you more information.
I'm using simple 3D color HLSL (VS and PS ver: 4.0) shader with alpha blending for the bigger triangle:
cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
}
struct VS_INPUT
{
float4 Pos : POSITION;
float4 Color : COLOR;
};
struct PS_INPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
PS_INPUT VS ( VS_INPUT input )
{
PS_INPUT output = (PS_INPUT)0;
input.Pos.w = 1.0f;
output.Pos = mul ( input.Pos, World );
output.Pos = mul ( output.Pos, View );
output.Pos = mul ( output.Pos, Projection );
output.Color = input.Color;
return output;
}
float4 PS ( PS_INPUT input ) : SV_Target
{
return input.Color;
}
That's my Vertex data struct:
struct Vertex
{
DirectX::XMFLOAT3 position;
DirectX::XMFLOAT4 color;
Vertex() {};
Vertex(DirectX::XMFLOAT3 aPosition, DirectX::XMFLOAT4 aColor)
: position(aPosition)
, color(aColor)
{};
};
Render call for object:
bool PrimitiveMesh::Draw()
{
unsigned int stride = sizeof(Vertex);
unsigned int offset = 0;
D3DSystem::GetD3DDeviceContext()->IASetVertexBuffers(0, 1, &iVertexBuffer, &stride, &offset);
D3DSystem::GetD3DDeviceContext()->IASetIndexBuffer(iIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
D3DSystem::GetD3DDeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
return true;
}
Draw call with initialization:
static PrimitiveMesh* mesh;
if (mesh == 0)
{
std::vector<PrimitiveMesh::Vertex> vertices;
mesh = new PrimitiveMesh();
DirectX::XMFLOAT4 color = { 186 / 256.0f, 186 / 256.0f, 186 / 256.0f, 0.8f };
vertices.push_back({ DirectX::XMFLOAT3(0.0f, 0.0f, 0.0f), color });
vertices.push_back({ DirectX::XMFLOAT3(0.0f, 600.0f, 0.0f), color });
vertices.push_back({ DirectX::XMFLOAT3(800.0f, 600.0f, 0.0f), color });
mesh->SetVerticesAndIndices(vertices);
}
// Getting clean matrices here:
D3D::Matrices(world, view, projection, ortho);
iGI->TurnZBufferOff();
iGI->TurnOnAlphaBlending();
mesh->Draw();
XMMATRIX view2D = Camera::View2D();
iColorShader->Render(iGI->GetContext(), 3, &world, &view2D, &ortho);
iGI->TurnZBufferOn();
These are my 2D calculations for camera:
up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
lookAt = DirectX::XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f);
rotationMatrix = DirectX::XMMatrixRotationRollPitchYaw(0.0f, 0.0f, 0.0f); // (pitch, yaw, roll);
up = DirectX::XMVector3TransformCoord(up, rotationMatrix);
lookAt = DirectX::XMVector3TransformCoord(lookAt, rotationMatrix) + position;
view2D = DirectX::XMMatrixLookAtLH(position, lookAt, up);
I'll appreciate any help.
Kind regards.
With Shaders, you are not forced to use matrices, you have the flexibility to simplify the problem.
Let say you render 2d objects, using coordinates in pixels, the only requirement, is to scale offset them back into the normalized projective space.
A vertex shader could be as short as that :
cbuffer ConstantBuffer : register( b0 ) {
float2 rcpDim; // 1 / renderTargetSize
}
PS_INPUT VS ( VS_INPUT input ) {
PS_INPUT output;
output.Pos.xy = input.Pos.xy * rcpDim * 2; // from pixel to [0..2]
output.Pos.xy -= 1; // to [-1..1]
output.Pos.y *= -1; // because top left in texture space is bottom left in projective space
output.Pos.zw = float2(0,1);
output.Color = input.Color;
return output;
}
You can of course build a set of matrices achieving the same result with your original shader, just set World and View to identity and projection to an ortho projection with XMMatrixOrthographicOffCenterLH(0,width,0,height,0,1). But as you are beggining with 3D programming, you will soon have to learn to deal with multiple shaders anyway, so take it as an exercice.
Well, I fixed my problem. For some weird reason, DirectXMath was generating false XMMATRIX. My XMMatrixOrtographicLH() was completely incorrect for good parameters. I solved my problem with classic definition of Ortohraphic matrix, found in this article (definition in Fig. 10)
auto orthoMatrix = DirectX::XMMatrixIdentity();
orthoMatrix.r[0].m128_f32[0] = 2.0f / Engine::VideoSettings::Current()->WindowWidth();
orthoMatrix.r[1].m128_f32[1] = 2.0f / Engine::VideoSettings::Current()->WindowHeight();
orthoMatrix.r[2].m128_f32[2] = -(2.0f / (screenDepth - screenNear));
orthoMatrix.r[2].m128_f32[3] = -(screenDepth + screenNear) / (screenDepth - screenNear);
galop1n give a good solution but on my system
cbuffer ConstantBuffer : register( b0 ) {
float2 rcpDim; // 1 / renderTargetSize
}
NEED to be a multiple of 16 for made like here:
struct VS_CONSTANT_BUFFER
{
DirectX::XMFLOAT2 rcpDim;
DirectX::XMFLOAT2 rcpDim2;
};
// Supply the vertex shader constant data.
VS_CONSTANT_BUFFER VsConstData;
VsConstData.rcpDim = { 2.0f / w,2.0f / h};
// Fill in a buffer description.
D3D11_BUFFER_DESC cbDesc;
ZeroMemory(&cbDesc, sizeof(cbDesc));
cbDesc.ByteWidth = sizeof(VS_CONSTANT_BUFFER);
cbDesc.Usage = D3D11_USAGE_DYNAMIC;
cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
cbDesc.MiscFlags = 0;
cbDesc.StructureByteStride = 0;
// Fill in the subresource data.
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = &VsConstData;
InitData.SysMemPitch = 0;
InitData.SysMemSlicePitch = 0;
// Create the buffer.
HRESULT hr = pDevice->CreateBuffer(&cbDesc, &InitData,
&pConstantBuffer11);
or aligned
__declspec(align(16))
struct VS_CONSTANT_BUFFER
{
DirectX::XMFLOAT2 rcpDim;
};

Lighting a cube with a shader issue

i've been following tutorials on directx 11 with a book and am now trying to give my code some lighting effects with a shader. But the problem is that it only shows the back buffer and doens't seem te make use of the lighting shader file at all. I am trying to light up a cube. Thanks for the help already.
HLSL:
struct DirectionalLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Direction;
float pad;
};
struct PointLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Position;
float Range;
float3 Att;
float pad;
};
struct SpotLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Position;
float Range;
float3 Direction;
float Spot;
float3 Att;
float pad;
};
struct Material
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float4 Reflect;
};
void ComputeDirectionalLight( Material mat, DirectionalLight L, float3 normal, float3 toEye, out float4 ambient, out float4 diffuse, out float4 spec)
{
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.0f);
float3 lightVec = -L.Direction;
ambient = mat.Ambient * L.Ambient;
float diffuseFactor = dot(lightVec, normal);
[flatten]
if( diffuseFactor > 0.0f )
{
float3 v = reflect(-lightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);
diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
}
void ComputePointLight(Material mat, PointLight L, float3 pos, float3 normal, float3 toEye, out float4 ambient, out float4 diffuse, out float4 spec)
{
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.0f);
float3 LightVec = L.Position - pos;
float d = length(LightVec);
if( d > L.Range )
return;
LightVec /= d;
ambient = mat.Ambient * L.Ambient;
float diffuseFactor = dot(LightVec, normal);
[flatten]
if(diffuseFactor > 0.0f)
{
float3 v = reflect(-LightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);
diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
float att = 1.0f / dot(L.Att, float3(1.0f, d, d*d));
diffuse *= att;
spec *= att;
}
void ComputeSpotLight(Material mat, SpotLight L, float3 pos, float3 normal, float3 toEye, out float4 ambient, out float4 diffuse, out float4 spec)
{
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.f);
float3 LightVec = L.Position - pos;
float d = length(LightVec);
if( d > L.Range )
return;
LightVec /= d;
ambient = mat.Ambient * L.Ambient;
float diffuseFactor = dot(LightVec, normal);
[flatten]
if( diffuseFactor > 0.0f )
{
float3 v = reflect(-LightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);
diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
float spot = pow(max(dot(-LightVec, L.Direction), 0.0f), L.Spot);
float att = spot / dot(L.Att, float3(1.0f, d, d*d));
ambient *= spot;
diffuse *= att;
spec *= att;
}
cbuffer cbPerFrame
{
DirectionalLight gDirLight;
PointLight gPointLight;
SpotLight gSpotLight;
float3 gEyePosW;
};
cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gWorldViewProj;
Material gMaterial;
};
struct VertexIn
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW: NORMAL;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
vout.PosW = mul(float4(vin.PosL, 1.0f), gWorld).xyz;
vout.NormalW = mul(vin.NormalL, (float3x3)gWorldInvTranspose);
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
pin.NormalW = normalize(pin.NormalW);
float3 toEyeW = normalize(gEyePosW - pin.PosW);
float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 A, D, S;
ComputeDirectionalLight(gMaterial, gDirLight, pin.NormalW, toEyeW, A, D, S);
ambient += A;
diffuse += D;
spec += S;
ComputePointLight(gMaterial, gPointLight, pin.PosW, pin.NormalW, toEyeW, A, D, S);
ambient += A;
diffuse += D;
spec += S;
ComputeSpotLight(gMaterial, gSpotLight, pin.PosW, pin.NormalW, toEyeW, A, D, S);
ambient += A;
diffuse += D;
spec += S;
float4 litColor = ambient + diffuse + spec;
litColor.a = gMaterial.Diffuse.a;
return litColor;
}
Code in my cpp file:
struct Vertex
{
XMFLOAT3 Pos;
XMFLOAT3 Normal;
};
struct CBUFFER{ XMMATRIX gWorldViewProj; };
class BoxApp : public Framework_App
{
public:
BoxApp(HINSTANCE hInstance);
~BoxApp();
bool Init();
void OnResize();
void UpdateScene(float dt);
void DrawScene();
void OnMouseDown(WPARAM BtnState, int x, int y);
void OnMouseUp(WPARAM BtnState, int x, int y);
void OnMouseMove(WPARAM BtnState, int x, int y);
private:
void BuildGeometryBuffers();
void BuildFX();
private:
ID3D11Buffer* mBoxVB;
ID3D11Buffer* mBoxIB;
ID3D11Buffer* mBoxCB = nullptr;
ID3D11VertexShader* pVS;
ID3D11PixelShader* pPS;
ID3D11InputLayout* mInputLayout;
XMFLOAT4X4 mWorld;
XMFLOAT4X4 mView;
XMFLOAT4X4 mProj;
XMFLOAT3 mEyePosW;
XMFLOAT3 GetNormal(float x, float z)const;
//licht variablen
DirectionalLight mDirLight;
PointLight mPointLight;
SpotLight mSpotLight;
Material mLandmat;
Material mWavesmat;
float mTheta;
float mPhi;
float mRadius;
float GetHeight(float x, float z)const;
POINT mLastMousePos;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
BoxApp theApp(hInstance);
if (!theApp.Init())
return 0;
return theApp.App_Run();
}
BoxApp::BoxApp(HINSTANCE hInstance)
: Framework_App(hInstance), mBoxVB(0), mBoxIB(0), mBoxCB(0) ,pVS(0), pPS(0), mInputLayout(0), mEyePosW(0.0f, 0.0f, 0.0f),
mTheta(1.5f*MathTools::HalfTau), mPhi(0.25f*MathTools::HalfTau), mRadius(5.0f)
{
mLastMousePos.x = 0;
mLastMousePos.y = 0;
XMMATRIX I = XMMatrixIdentity();
XMStoreFloat4x4(&mWorld, I);
XMStoreFloat4x4(&mView, I);
XMStoreFloat4x4(&mProj, I);
//directional light
mDirLight.Ambient = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
mDirLight.Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mDirLight.Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mDirLight.Direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f);
//point light
mPointLight.Ambient = XMFLOAT4(0.3f, 0.3, 0.3f, 1.0f);
mPointLight.Diffuse = XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f);
mPointLight.Specular = XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f);
mPointLight.Att = XMFLOAT3(0.0f, 0.1f, 0.0f);
mPointLight.Range = 25.0f;
//spot light
mSpotLight.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
mSpotLight.Diffuse = XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f);
mSpotLight.Specular = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
mSpotLight.Att = XMFLOAT3(1.0f, 0.0f, 0.0f);
mSpotLight.Spot = 96.0f;
mSpotLight.Range = 1000.0f;
//materials
mLandmat.Ambient = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
mLandmat.Diffuse = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
mLandmat.Specular = XMFLOAT4(0.2f, 0.2f, 0.2f, 16.0f);
}
BoxApp::~BoxApp()
{
ReleaseCOM(mBoxVB);
ReleaseCOM(mBoxIB);
ReleaseCOM(mBoxCB);
ReleaseCOM(pVS);
ReleaseCOM(pPS);
ReleaseCOM(mInputLayout);
}
bool BoxApp::Init()
{
if (!Framework_App::App_Init())
return false;
BuildGeometryBuffers();
BuildFX();
return true;
}
void BoxApp::OnResize()
{
Framework_App::OnResize();
// The window resized, so update the aspect ratio and recompute the projection matrix.
XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathTools::HalfTau, AspectRatio(), 1.0f, 1000.0f);
XMStoreFloat4x4(&mProj, P);
}
void BoxApp::UpdateScene(float dt)
{
// Convert Spherical to Cartesian coordinates.
float x = mRadius*sinf(mPhi)*cosf(mTheta);
float z = mRadius*sinf(mPhi)*sinf(mTheta);
float y = mRadius*cosf(mPhi);
mEyePosW = XMFLOAT3(x, y ,z);
// Build the view matrix.
XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
XMVECTOR target = XMVectorZero();
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
XMStoreFloat4x4(&mView, V);
//update lights
mPointLight.Position.x = 70.0f*cosf(0.2f*mTimer.Totaltime());
mPointLight.Position.z = 70.0f*sinf(0.2f*mTimer.Totaltime());
mPointLight.Position.y = MathTools::Max(GetHeight(mPointLight.Position.x, mPointLight.Position.z), -3.0f) + 10.0f;
mSpotLight.Position = mEyePosW;
XMStoreFloat3(&mSpotLight.Direction, XMVector3Normalize(target - pos));
}
void BoxApp::DrawScene()
{
MainDevContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::LightSteelBlue));
MainDevContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
MainDevContext->IASetInputLayout(mInputLayout);
MainDevContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
UINT stride = sizeof(Vertex);
UINT offset = 0;
MainDevContext->IASetVertexBuffers(0, 1, &mBoxVB, &stride, &offset);
MainDevContext->IASetIndexBuffer(mBoxIB, DXGI_FORMAT_R32_UINT, 0);
// Set constants
XMMATRIX world = XMLoadFloat4x4(&mWorld);
XMMATRIX view = XMLoadFloat4x4(&mView);
XMMATRIX proj = XMLoadFloat4x4(&mProj);
XMMATRIX worldViewProj = world*view*proj;
XMMATRIX worldViewProjTRNS = XMMatrixTranspose(worldViewProj);
CBUFFER cBuffer;
cBuffer.gWorldViewProj = worldViewProjTRNS;
MainDevContext->UpdateSubresource(mBoxCB, 0, 0, &cBuffer, 0, 0);
MainDevContext->DrawIndexed(36, 0, 0);
mSwapChain->Present(0, 0);
}
void BoxApp::OnMouseDown(WPARAM BtnState, int x, int y)
{
mLastMousePos.x = x;
mLastMousePos.y = y;
SetCapture(FrmeWrkMainWnd);
}
void BoxApp::OnMouseUp(WPARAM BtnState, int x, int y)
{
ReleaseCapture();
}
void BoxApp::OnMouseMove(WPARAM BtnState, int x, int y)
{
if ((BtnState & MK_LBUTTON) != 0)
{
// Make each pixel correspond to a quarter of a degree.
float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));
// Update angles based on input to orbit camera around box.
mTheta += dx;
mPhi += dy;
// Restrict the angle mPhi.
mPhi = MathTools::Clamp(mPhi, 0.1f, MathTools::HalfTau - 0.1f);
}
else if ((BtnState & MK_RBUTTON) != 0)
{
// Make each pixel correspond to 0.005 unit in the scene.
float dx = 0.005f*static_cast<float>(x - mLastMousePos.x);
float dy = 0.005f*static_cast<float>(y - mLastMousePos.y);
// Update the camera radius based on input.
mRadius += dx - dy;
// Restrict the radius.
mRadius = MathTools::Clamp(mRadius, 3.0f, 15.0f);
}
mLastMousePos.x = x;
mLastMousePos.y = y;
}
void BoxApp::BuildGeometryBuffers()
{
// Create vertex buffer
Vertex vertices[] =
{
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), (const float*)&Colors::White },
{ XMFLOAT3(-1.0f, +1.0f, -1.0f), (const float*)&Colors::Black },
{ XMFLOAT3(+1.0f, +1.0f, -1.0f), (const float*)&Colors::Red },
{ XMFLOAT3(+1.0f, -1.0f, -1.0f), (const float*)&Colors::Green },
{ XMFLOAT3(-1.0f, -1.0f, +1.0f), (const float*)&Colors::Blue },
{ XMFLOAT3(-1.0f, +1.0f, +1.0f), (const float*)&Colors::Yellow },
{ XMFLOAT3(+1.0f, +1.0f, +1.0f), (const float*)&Colors::Cyan },
{ XMFLOAT3(+1.0f, -1.0f, +1.0f), (const float*)&Colors::Magneta }
};
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex)* 8;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = vertices;
MainD3DDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB);
// Create the index buffer
UINT indices[] = {
// front face
0, 1, 2,
0, 2, 3,
// back face
4, 6, 5,
4, 7, 6,
// left face
4, 5, 1,
4, 1, 0,
// right face
3, 2, 6,
3, 6, 7,
// top face
1, 5, 6,
1, 6, 2,
// bottom face
4, 0, 3,
4, 3, 7
};
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT)* 36;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices;
MainD3DDevice->CreateBuffer(&ibd, &iinitData, &mBoxIB);
}
float BoxApp::GetHeight(float x, float z)const
{
return 0.3f*(z*sinf(0.1f*x) + x*cosf(0.1*z));
}
XMFLOAT3 BoxApp::GetNormal(float x, float z)const
{
XMFLOAT3 n(-0.03f*z*cosf(0.1f*x) - 0.3f*cosf(0.1f*z), 1.0f, -0.3f*sinf(0.1f*x) - 0.03f*x*sinf(0.1f*z));
XMVECTOR unitNormal = XMVector3Normalize(XMLoadFloat3(&n));
XMStoreFloat3(&n, unitNormal);
return n;
}
void BoxApp::BuildFX()
{
ID3D10Blob* VS;
ID3D10Blob* PS;
D3DX11CompileFromFile((LPSTR)"mColor.shader",0,0, "VS", "vs_4_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile((LPSTR)"mColor.shader", 0, 0, "PS", "ps_4_0", 0, 0, 0, &PS, 0, 0);
MainD3DDevice->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
MainD3DDevice->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
MainDevContext->VSSetShader(pVS, 0, 0);
MainDevContext->PSSetShader(pPS, 0, 0);
D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
MainD3DDevice->CreateInputLayout(vertexDesc, 2, VS->GetBufferPointer(), VS->GetBufferSize() ,&mInputLayout);
MainDevContext->IASetInputLayout(mInputLayout);
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(CBUFFER);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
MainD3DDevice->CreateBuffer(&bd, nullptr, &mBoxCB);
MainDevContext->VSSetConstantBuffers(0, 1, &mBoxCB);
}
I Think you have alot of errors in this code.
Folow these tutorials aswell, It might be easier to get the whole view then:
http://web.archive.org/web/20140213145557/http://rastertek.com/tutdx11.html
One example, you run BuildFX() at the start, I am pretty sure you should set these two functions every frame
MainDevContext->VSSetShader(pVS, 0, 0);
MainDevContext->PSSetShader(pPS, 0, 0);
Have you succeded to Rendered a cube with pure colors yet? If so you should just build from there.
There is alot of code to mention but the last 5 functions i run every frame is those:
deviceContext->IASetInputLayout(m_layout);
deviceContext->VSSetShader(m_vertexShader, NULL, 0);
deviceContext->PSSetShader(m_pixelShader, NULL, 0);
deviceContext->PSSetSamplers(0, 1, &m_sampleState);
deviceContext->DrawIndexed(indexCount, 0, 0);
Read the link and reduce down your errors. I havent read all of your code.

C++ Directx 11 Ambient Lighting

I'm currently having a problem with lighting in Directx 11, actually its ambient lighting. Here is the code:
cbuffer ConstantBuffer
{
float4x4 final;
float4x4 rotation; // the rotation matrix
float4 lightvec; // the light's vector
float4 lightcol; // the light's color
float4 ambientcol; // the ambient light's color
}
struct VOut
{
float4 color : COLOR;
float4 position : SV_POSITION;
};
VOut VShader(float4 position : POSITION, float4 normal : NORMAL)
{
VOut output;
output.position = mul(final, position);
// set the ambient light
output.color = ambientcol;
// calculate the diffuse light and add it to the ambient light
float4 norm = normalize(mul(rotation, normal));
float diffusebrightness = saturate(dot(norm, lightvec));
output.color += lightcol * diffusebrightness;
return output;
}
float4 PShader(float4 color : COLOR) : SV_TARGET
{
return color;
}
Then i send the values to the shader:
ambLight.LightVector = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 0.0f);
ambLight.LightColor = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);
ambLight.AmbientColor = D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f);
ShaderManager.UpdateSubresourceDiffuseShader(devcon);
And then i get the following:
Why?
I tried your shader and seems to work, so maybe some variable are not passed correctly.
you could try to directly set one variable name to color output:
output.color = lightvec;
and
output.color = lightcol;
As a start, so you could double check values are passed properly.