2D Programming with Direct3D 9 - Test image is distorted - directx

I am trying to build a simple 2D game using 2D sprites with DirectX 9, and I'm having problems getting the images to come out cleanly. I'd like to load bmp images and display them on the screen as is (no interpolation, no magnification, no filtering or anti-aliasing, etc).
I'm sure I'm missing something, but when I try and render a 100x100 bmp to the screen, it looks choppy and distorted, like a pixel art image would normally look when shrunken slightly. I want the bmp to look exactly as it does when loaded in MS Paint.
Does anyone have any idea why this might be the case? My code is shown below:
Initialization code:
g_DxCom = Direct3DCreate9( D3D_SDK_VERSION );
if ( g_DxCom == NULL )
{
return false;
}
D3DDISPLAYMODE d3dDisplayMode;
if ( FAILED( g_DxCom->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3dDisplayMode ) ) )
{
return false;
}
D3DPRESENT_PARAMETERS d3dPresentParameters;
::ZeroMemory( &d3dPresentParameters, sizeof(D3DPRESENT_PARAMETERS) );
d3dPresentParameters.Windowed = FALSE;
d3dPresentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dPresentParameters.BackBufferFormat = d3dDisplayMode.Format; // D3DFMT_X8R8G8B8
d3dPresentParameters.BackBufferWidth = d3dDisplayMode.Width;
d3dPresentParameters.BackBufferHeight = d3dDisplayMode.Height;
d3dPresentParameters.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
if ( FAILED( g_DxCom->CreateDevice( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
this->hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dPresentParameters,
&pd3dDevice ) ) )
{
if ( FAILED( g_DxCom->CreateDevice( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
this->hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dPresentParameters,
&pd3dDevice ) ) )
{
return false;
}
}
texture = NULL;
bg_texture = NULL;
Render code:
LPDIRECT3DDEVICE9 g_dxDevice;
float float1 = 99.5f; // I'd like to render my 100x100 sprite from screen coordinates 100, 100 to 200, 200
float float2 = 198.5f;
CUSTOMVERTEX OurVertices[] =
{
{ float1, float2, 1.0f, 1.0f, 0.0f, 1.0f },
{ float1, float1, 1.0f, 1.0f, 0.0f, 0.0f },
{ float2, float1, 1.0f, 1.0f, 1.0f, 0.0f },
{ float1, float2, 1.0f, 1.0f, 0.0f, 1.0f },
{ float2, float1, 1.0f, 1.0f, 1.0f, 0.0f },
{ float2, float2, 1.0f, 1.0f, 1.0f, 1.0f }
};
LPDIRECT3DVERTEXBUFFER9 v_buffer;
g_dxDevice->CreateVertexBuffer( 6 * sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL );
VOID* pVoid;
// Lock the vertex buffer into memory
v_buffer->Lock( 0, 0, &pVoid, 0 );
// Copy our vertex buffer to memory
::memcpy( pVoid, OurVertices, sizeof(OurVertices) );
// Unlock buffer
v_buffer->Unlock();
LPDIRECT3DTEXTURE9 g_texture;
HRESULT hError;
DWORD dwTextureFilter = D3DTEXF_NONE;
g_dxDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, dwTextureFilter );
g_dxDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, dwTextureFilter );
g_dxDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, dwTextureFilter );
g_dxDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
g_dxDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
g_dxDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
hError = D3DXCreateTextureFromFile( g_dxDevice, L"Test.bmp", &g_texture ); // 100x100 sprite
g_dxDevice->SetTexture( 0, g_texture );
g_dxDevice->Clear( 0,
NULL,
D3DCLEAR_TARGET,
D3DCOLOR_XRGB( 0, 40, 100 ),
1.0f,
0 );
g_dxDevice->BeginScene();
// Do rendering on the back buffer here
g_dxDevice->SetFVF( CUSTOMFVF );
g_dxDevice->SetStreamSource( 0, v_buffer, 0, sizeof(CUSTOMVERTEX) );
g_dxDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 6 );
g_dxDevice->EndScene();
g_dxDevice->Present( NULL, NULL, NULL, NULL );
g_texture->Release();
v_buffer->Release();

Okay, so I've finally figured it out, and I should have known this was the case.
It looks like DirectX9 only works with textures with sizes that are multiples of 2. If I change the texture so that the sprite square is 128 x 128 (just adding some transparency) and run the application with float2 changed appropriately, there is no distortion in the rendered image.
Hurrah...

Related

How to copy the RTV output to the side of a cubemap?

I am currently implementing diffuse irridiance(A part of Image based lightning of PBR) in my game engine. I got to the point where I have to take an HDR Image and turn it into a cubemap. I am currently using a EquirectangularToCubemap shader and its working fine. I was able to project the HDR image to a (unit)cube. Now comes the part where I am stuck, I can't turn this cube to a cubemap. I tried using 1 TextureCube, 6 RenderTargetView's and a ShaderResourceView. My plan was to render the (unit)cube 6 times from different view projection with a FOV of 90 to capture the whole side in each of the render target, and lastly copy each of the output of the render target to the corresponding side of the Texture cube.
I don't know how to do this ^.
NOTE: I am using DirextX11 as the rendering backend.
Here is the pseudo code about my problem(which is not working)
glm::mat4 captureProjection = glm::perspective(glm::radians(90.0f), 1.0f, 0.1f, 10.0f);
glm::mat4 captureViews[] =
{
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(-1.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, -1.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f), glm::vec3(0.0f, -1.0f, 0.0f)),
glm::lookAt(glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec3(0.0f, -1.0f, 0.0f))
};
//Create the TextureCube
D3D11_TEXTURE2D_DESC textureDesc = {};
textureDesc.Width = 512;
textureDesc.Height = 512;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 6;
textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
textureDesc.CPUAccessFlags = 0;
textureDesc.SampleDesc.Count = 1;
textureDesc.SampleDesc.Quality = 0;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
textureDesc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
ID3D11Texture2D* tex = nullptr;
DX_CALL(DX11Internal::GetDevice()->CreateTexture2D(&textureDesc, nullptr, &tex));
// Create the Shader Resource view for the texture cube
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
srvDesc.Format = textureDesc.Format;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
srvDesc.Texture2D.MostDetailedMip = 0;
srvDesc.Texture2D.MipLevels = 1;
DX_CALL(DX11Internal::GetDevice()->CreateShaderResourceView(tex, &srvDesc, &mSRV));
//Create the Render target views
Vector<ID3D11RenderTargetView*> rtvs;
for (Uint i = 0; i < 6; i++)
{
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc = {};
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
ID3D11RenderTargetView* view = nullptr;
DX11Internal::GetDevice()->CreateRenderTargetView(tex, &renderTargetViewDesc, &view);
rtvs.push_back(view);
}
tex->Release();
auto deviceContext = DX11Internal::GetDeviceContext();
for (Uint i = 0; i < 6; ++i)
{
float clearColor[4] = { 1.0f, 0.1f, 0.1f, 1.0f };
deviceContext->ClearRenderTargetView(rtvs[i], clearColor);
Vault::Get<Shader>("EquirectangularToCubemap.hlsl")->Bind();
auto data = captureProjection * captureViews[i];
cbuffer->Bind();
cbuffer->SetData(&data);
texture->Bind(0);
tempPipeline->Bind();
deviceContext->OMSetRenderTargets(1, &rtvs[i], nullptr);
//I am rendering the cube here from different view projection to capture the faces, but I dont't know where to copy the data to the //side of the TextureCube :( [Note that I am doing this only once]
RenderCommand::DrawIndexed(tempPipeline, 36);
}
Thanks in advance!
You are not specifying which slices you want to write to when creating render views.
The correct description for slices is:
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc = {};
renderTargetViewDesc.Format = textureDesc.Format;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
renderTargetViewDesc.Texture2DArray.MipSlice = 0;
renderTargetViewDesc.Texture2DArray.FirstArraySlice =i;
renderTargetViewDesc.Texture2DArray.ArraySize = 1;
(Note : if you use MSAA, ViewDimension will become D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY)
Also to create the shader view for your resource, since you want to create a default one, you can pass NULL instead of a home made D3D11_SHADER_RESOURCE_VIEW_DESC
DX_CALL(DX11Internal::GetDevice()->CreateShaderResourceView(tex, NULL, &mSRV));
You can also create another render view that maps the whole cube map in one go :
DX11Internal::GetDevice()->CreateRenderTargetView(tex, NULL, &cubeMapFullView);
But in that case you will need to use Geometry Shader to replicate geometry across slices (using SV_RenderTargetArrayIndex), or use vendor specific extensions that provide the same kind of feature.

DX11 triangle list is not rendering at all

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.

Direct3D9 not drawing?

I needed to draw some simple shapes and I decided to go with D3D9. After going through a few of the tutorials on directxtutorial.com, I finally have all the code and knowledge I need to make my first shape appear on the screen. The problem is, though, that no image is appearing. I've looked over the code many times and have compared it with the code on the website, and it all checks out. Why is nothing rendering on the screen?
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DVERTEXBUFFER9 vbuffer;
struct CUSTOMVERTEX
{
float x, y, z, rhw;
DWORD color;
};
void InitD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.hDeviceWindow = hWnd;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
}
void InitGraphics()
{
CUSTOMVERTEX verticies[]
{
{50, 70, 1.0f, 1.0f, D3DCOLOR_XRGB(250, 0, 0),},
{70, 50, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 250, 0),},
{40, 80, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 250),},
};
d3ddev->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX), NULL, CUSTOMFVF, D3DPOOL_MANAGED, &vbuffer, NULL);
void* vp;
vbuffer->Lock(0, 0, (void**)&vp, NULL);
memcpy(vp, verticies, sizeof(verticies));
vbuffer->Unlock();
}
void Draw()
{
d3ddev->Clear(NULL, NULL, D3DCLEAR_TARGET, NULL, 1.0f, NULL);
d3ddev->BeginScene();
d3ddev->SetFVF(CUSTOMFVF);
d3ddev->SetStreamSource(0, vbuffer, 0, sizeof(CUSTOMVERTEX));
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
d3ddev->EndScene();
d3ddev->Present(NULL, NULL, NULL, NULL);
}
void ReleaseD3D()
{
d3d->Release();
d3ddev->Release();
vbuffer->Release();
}
Turns out my vertex positions weren't triangle enough to make a triangle. Thanks for the help, though, it reminded me to set up error-checking.

How to create two objects from one vertices array with translate?

I have an object and I can render it but I want to use its vertices twice but I don't know how to.
Edit: I wan them to translate independently during the game.
this is my code reading object from txt:
fin.open("piyon.txt");
fin >> vertexCountpiyon;
verticespiyon = new SimpleVertex[vertexCountpiyon];
for(int i=0; i<vertexCountpiyon; i++)
{
fin >> verticespiyon[i].Pos.x >> verticespiyon[i].Pos.y >> verticespiyon[i].Pos.z;
fin >> verticespiyon[i].Tex.x >> verticespiyon[i].Tex.y;
fin >> verticespiyon[i].Normal.x >> verticespiyon[i].Normal.y >> verticespiyon[i].Normal.z;
}
fin.close();
bd.ByteWidth = sizeof( SimpleVertex ) * vertexCountpiyon;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = verticespiyon;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer_piyon );
if( FAILED( hr ) ) return hr;
and my render code:
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer_piyon, &stride, &offset );
cBuffer.vMeshColor = XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f );
XMMATRIX mTranslateBeyazPiyon = XMMatrixTranslation( -17.5F, 0, -12.5F );
cBuffer.mWorld = XMMatrixTranspose( mTranslateBeyazPiyon );
g_World_Piyon = mTranslateBeyazPiyon;
g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cBuffer, 0, 0 );
g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );
g_pImmediateContext->VSSetConstantBuffers( 2, 1, &g_pConstantBuffer );
g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
g_pImmediateContext->PSSetConstantBuffers( 2, 1, &g_pConstantBuffer );
g_pImmediateContext->Draw( 7050, 0 );
If you want to just draw the same object in a different place, you only need to change your world matrix and then draw again. So, using parts of your code for reference, something like this:
// set world matrix for first object ...
XMMATRIX mTranslateBeyazPiyon = XMMatrixTranslation( -17.5F, 0, -12.5F );
cBuffer.mWorld = XMMatrixTranspose( mTranslateBeyazPiyon );
g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cBuffer, 0, 0 );
// ... set any other common state
// draw first object
g_pImmediateContext->Draw( 7050, 0 );
// set world matrix for second object ... for example, translated somewhere else
mTranslateBeyazPiyon = XMMatrixTranslation( -34.5F, 0, -24.5F );
cBuffer.mWorld = XMMatrixTranspose( mTranslateBeyazPiyon );
g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cBuffer, 0, 0 );
// draw second object
g_pImmediateContext->Draw( 7050, 0 );

scene became a mess when I drew mirror reflection(dx9)

In my project, I draw a house, which consists of wall, floor, mirror, a switch to turn on or turn off the fire system. Everything is going on well by here.
At last, I want to draw a person's reflection on the mirror, but after I add the drawReflection function, things go wrong, scene became a mess. Why? I write the function according to the book.
void House::draw(float timeDelta)
{
_device->SetFVF(d3d::Vertex::FVF);
_device->SetStreamSource(0, _vb, 0, sizeof(d3d::Vertex));
// draw wall
_device->SetMaterial(&d3d::WHITE_MTRL);
_device->SetTexture(0, _wall);
_device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 10);
// draw floor
_device->SetMaterial(&d3d::WHITE_MTRL);
_device->SetTexture(0, _floor);
_device->DrawPrimitive(D3DPT_TRIANGLELIST, 30, 2);
// draw mirror
_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
_device->SetMaterial(&d3d::WHITE_MTRL);
_device->SetTexture(0, _mirror);
_device->DrawPrimitive(D3DPT_TRIANGLELIST, 36, 2);
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
// draw switch button
D3DXMATRIX T, Ry, P;
D3DXMatrixTranslation(&T, -4.95f, 2.0f, 3.0f);
D3DXMatrixRotationY(&Ry, D3DX_PI * 1.5f);
P = Ry * T;
_device->SetTransform(D3DTS_WORLD, &P);
_device->SetMaterial(&d3d::BLUE_MTRL);
_device->SetTexture(0, NULL);
_switch->DrawSubset(0);
// draw fire system
D3DXMATRIX I;
D3DXMatrixIdentity(&I);
_device->SetTransform(D3DTS_WORLD, &I);
if(_fSwitchOn)
{
if(_fs->isDead())
_fs->reset();
_fs->update(timeDelta);
_fs->render();
}
// draw reflection of person
//drawReflection();
}
But after I add drawReflection() function to it, it became a mess. Why?
drawReflection() function is below:
void House::drawReflection()
{
// enable stencil
_device->SetRenderState(D3DRS_STENCILENABLE, true);
_device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
_device->SetRenderState(D3DRS_STENCILREF, 0x1);
_device->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);
_device->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
_device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
_device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
_device->SetRenderState(D3DRS_STENCILPASS,
D3DSTENCILOP_REPLACE);
// stop write to target buffer and depth buffer
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
_device->SetRenderState(D3DRS_ZWRITEENABLE, false);
// draw the mirror to stencil buffer
_device->SetFVF(d3d::Vertex::FVF);
_device->SetStreamSource(0, _vb, 0, sizeof(d3d::Vertex));
_device->SetMaterial(&d3d::WHITE_MTRL);
_device->SetTexture(0, _mirror);
D3DXMATRIX I;
D3DXMatrixIdentity(&I);
_device->SetTransform(D3DTS_WORLD, &I);
_device->DrawPrimitive(D3DPT_TRIANGLELIST, 36, 2);
_device->SetRenderState(D3DRS_ZWRITEENABLE, true);
// transform the mesh
_device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
_device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
D3DXMATRIX Reflect, S, T, P;
D3DXPLANE plane(0.0f, 0.0f, 1.0f, -5.0f);
D3DXMatrixReflect(&Reflect, &plane);
// D3DXMatrixScaling(&S, 0.2f, 0.2f, 0.2f);
D3DXVECTOR3 pos;
_person->getPosition(&pos);
D3DXMatrixTranslation(&T, pos.x, pos.y, pos.z);
P = T * Reflect;
_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_DESTCOLOR);
_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
_device->SetTransform(D3DTS_WORLD, &P);
_person->draw();
_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
_device->SetRenderState(D3DRS_STENCILENABLE, false);
_device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
}

Resources