在DirectX中渲染粒子的正方形的问题 [英] Problems rendering squares for particles in DirectX

查看:84
本文介绍了在DirectX中渲染粒子的正方形的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试渲染粒子的三角形列表。每个粒子是4个顶点和6个索引。它看起来像一个矩形,但它应该是一个正方形,因为我发送的顶点距离彼此相等。我正在使用Windows Phone 8的C#/ XAML和DirectX
组件作为项目。我拿了CubeRenderer.cpp文件并更改了它。但是使用视图&投影设置导致我的屏幕只绘制默认的黑色背景。但是,当我设置视图&投射到Identity矩阵,我可以看到正在绘制的矩形

I'm trying to render a trianglelist of particles. Each particle is 4 vertices, and 6 indices. It looks like a rectangle, but it should be a square as I've sent the vertices equal distances from each other. I'm using Windows Phone 8's C#/XAML with DirectX component as the project. I took the CubeRenderer.cpp files and changed it. But using the view & projection set there causes my screen to just draw the default black background. But when I set view & projection to Identity matrix, I can see rectangles being drawn.

我不知道我的代码的哪一部分是不正确的,所以希望这里显示的更多代码会有所帮助。请给我一些关于如何调试此问题的提示或指示。谢谢

I don't which part of my code is incorrect, so hopefully more code shown here will help. Please give me some tips or pointers on how to debug this issue. Thank you

void CubeRenderer::CreateParticleResources()
{
	auto loadVSTask = DX::ReadDataAsync("ParticleVertexShader.cso");
	auto loadPSTask = DX::ReadDataAsync("ParticlePixelShader.cso");

	auto createVSTask = loadVSTask.then([this](Platform::Array<byte>^ fileData) {
		DX::ThrowIfFailed(
			m_d3dDevice->CreateVertexShader(
				fileData->Data,
				fileData->Length,
				nullptr,
				&m_vertexShader
				)
			);

		const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = 
		{
			{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
			{ "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		};

		DX::ThrowIfFailed(
			m_d3dDevice->CreateInputLayout(
				vertexDesc,
				ARRAYSIZE(vertexDesc),
				fileData->Data,
				fileData->Length,
				&m_inputLayout
				)
			);
	});

	auto createPSTask = loadPSTask.then([this](Platform::Array<byte>^ fileData) {
		DX::ThrowIfFailed(
			m_d3dDevice->CreatePixelShader(
				fileData->Data,
				fileData->Length,
				nullptr,
				&m_pixelShader
				)
			);

		D3D11_BUFFER_DESC matrixBufferDesc;
		matrixBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
		matrixBufferDesc.ByteWidth = sizeof(ModelViewProjectionConstantBuffer);
		matrixBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
		matrixBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
		matrixBufferDesc.MiscFlags = 0;
		matrixBufferDesc.StructureByteStride = 0;

		DX::ThrowIfFailed(
			m_d3dDevice->CreateBuffer(
				&matrixBufferDesc,
				nullptr,
				&m_constantBuffer
				)
			);
	});

	auto createCubeTask = (createPSTask && createVSTask).then([this] () {
		
		m_vertexCount = m_maxParticles * 4;		m_indexCount = m_maxParticles * 6; 		m_vertices = new VertexType[m_vertexCount];
		if(!m_vertices)
		{
			OutputDebugString(L"Can't create the vertex array for the particles that will be rendered.");
		}
		else
		{
			m_totalSizeVertices = m_sizeVertexType * m_vertexCount;
			memset(m_vertices, 0, m_totalSizeVertices);
			D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
			vertexBufferData.pSysMem = m_vertices;
			vertexBufferData.SysMemPitch = 0;
			vertexBufferData.SysMemSlicePitch = 0;

			int sizeOfMVertices = sizeof(m_vertices);
			CD3D11_BUFFER_DESC vertexBufferDesc(
				m_totalSizeVertices,			// byteWidth
				D3D11_BIND_VERTEX_BUFFER,	// bindFlags
				D3D11_USAGE_DYNAMIC,		// D3D11_USAGE usage = D3D11_USAGE_DEFAULT
				D3D11_CPU_ACCESS_WRITE,		// cpuaccessFlags
				0,							// miscFlags
				0							// structureByteStride
				);

			OutputDebugString(L"Create vertex buffer\n");

			DX::ThrowIfFailed(
				m_d3dDevice->CreateBuffer(
					&vertexBufferDesc,
					&vertexBufferData,
					&m_vertexBuffer
					)
				);
		}
		unsigned short * indices = new unsigned short[m_indexCount];
		if(!indices)
		{
			OutputDebugString(L"Can't create the index array.");
		}
		else
		{
			// Initialize the index array.
			//for(int i=0; i<m_indexCount; i++)
			//{
			//	indices[i] = i;
			//}
			for(int i = 0; i < m_maxParticles; ++i)
			{
				const unsigned int i6 = i*6;
				const unsigned int i4 = i*4;
				indices[i6+0] = i4+0;
				indices[i6+1] = i4+1;
				indices[i6+2] = i4+2;
				indices[i6+3] = i4+0;
				indices[i6+4] = i4+2;
				indices[i6+5] = i4+3;
				//indices[i6+0] = i4+0;
				//indices[i6+1] = i4+1;
				//indices[i6+2] = i4+2;
				//indices[i6+3] = i4+2;
				//indices[i6+4] = i4+1;
				//indices[i6+5] = i4+3;
			}

			int sizeShort = sizeof(unsigned short);
			D3D11_BUFFER_DESC indexBufferDesc;
			indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
			indexBufferDesc.ByteWidth = sizeof(unsigned short) * m_indexCount;
			indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
			indexBufferDesc.CPUAccessFlags = 0;
			indexBufferDesc.MiscFlags = 0;
			indexBufferDesc.StructureByteStride = 0;

			D3D11_SUBRESOURCE_DATA indexData;		
			indexData.pSysMem = indices;
			indexData.SysMemPitch = 0;
			indexData.SysMemSlicePitch = 0;

			// Create the index buffer.
			DX::ThrowIfFailed(
				m_d3dDevice->CreateBuffer(
					&indexBufferDesc,
					&indexData,
					&m_indexBuffer
					)
				);
		
			
			delete [] indices;
			indices = 0;

		}

	});

	createCubeTask.then([this] () {		
		m_loadingComplete = true;
	});
}
void CubeRenderer::Update(float timeTotal, float timeDelta)
{
	if (!m_loadingComplete)
	{
		return;
	}

	XMVECTOR eye = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
	XMVECTOR at = XMVectorSet(0.0f, -0.1f, 0.0f, 0.0f);
	XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);

	XMStoreFloat4x4(&m_constantBufferData.view, XMMatrixTranspose(XMMatrixLookAtRH(eye, at, up)));
		
	Frame(timeTotal, timeDelta);
}

bool CubeRenderer::Frame(float frameTime, float deltaTime)
{
	bool result;
	// Release old particles.
	KillParticles();

	// Emit new particles.
	EmitParticles(frameTime);
	
	// Update the position of the particles.
	UpdateParticles(deltaTime);

	result = UpdateBuffers();
	if(!result)
	{
		return false;
	}

	return true;
}

bool CubeRenderer::UpdateBuffers()
{
	// Initialize vertex array to zeros at first.
	memset(m_vertices, 0, m_totalSizeVertices);

	// Now build the vertex array from the particle list array.  Each particle is a quad made out of two triangles.
	int index = 0;


	for(int i = 0; i < m_currentParticleCount; ++i)
	{
		// Bottom right.
		m_vertices[index].position =  XMFLOAT3(m_particleList[i].positionX + m_particleSize, m_particleList[i].positionY - m_particleSize, m_particleList[i].positionZ);
		m_vertices[index].texture =  XMFLOAT2(1.0f, 1.0f);
		m_vertices[index].color =   XMFLOAT4(m_particleList[i].red, m_particleList[i].green, m_particleList[i].blue, 1.0f);
		index++;

		// Bottom left.
		m_vertices[index].position = XMFLOAT3(m_particleList[i].positionX - m_particleSize, m_particleList[i].positionY - m_particleSize, m_particleList[i].positionZ);
		m_vertices[index].texture =  XMFLOAT2(0.0f, 1.0f);
		m_vertices[index].color =  XMFLOAT4(m_particleList[i].red, m_particleList[i].green, m_particleList[i].blue, 1.0f);
		index++;
				
		// Top left.
		m_vertices[index].position =  XMFLOAT3(m_particleList[i].positionX - m_particleSize, m_particleList[i].positionY + m_particleSize, m_particleList[i].positionZ);
		m_vertices[index].texture =  XMFLOAT2(0.0f, 0.0f);
		m_vertices[index].color =   XMFLOAT4(m_particleList[i].red, m_particleList[i].green, m_particleList[i].blue, 1.0f);
		index++;
		
		// Top right.
		m_vertices[index].position =  XMFLOAT3(m_particleList[i].positionX + m_particleSize, m_particleList[i].positionY + m_particleSize, m_particleList[i].positionZ);
		m_vertices[index].texture =  XMFLOAT2(1.0f, 0.0f);
		m_vertices[index].color =   XMFLOAT4(m_particleList[i].red, m_particleList[i].green, m_particleList[i].blue, 1.0f);
		index++;

	}

	D3D11_MAPPED_SUBRESOURCE mappedResource;	
	
	DX::ThrowIfFailed(m_d3dContext->Map(m_vertexBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
	VertexType * verticesPtr = (VertexType*)mappedResource.pData;
	memcpy(verticesPtr, (void*)m_vertices, m_totalSizeVertices);
	m_d3dContext->Unmap(m_vertexBuffer.Get(), 0);

	return true;
}

void CubeRenderer::SetShaderParameters()
{
	ModelViewProjectionConstantBuffer* dataPtr;
	unsigned int bufferNumber;
	
	D3D11_MAPPED_SUBRESOURCE mappedResource;
	DX::ThrowIfFailed(m_d3dContext->Map(m_constantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource));
	dataPtr = (ModelViewProjectionConstantBuffer*)mappedResource.pData;

	// Copy the matrices into the constant buffer.
	// GIVES no particles, just the black background
	//dataPtr->view = m_constantBufferData.view;
	//dataPtr->projection = m_constantBufferData.projection;

	XMStoreFloat4x4(&dataPtr->view, XMMatrixIdentity());
	XMStoreFloat4x4(&dataPtr->projection, XMMatrixIdentity());
	m_d3dContext->Unmap(m_constantBuffer.Get(), 0);

	m_d3dContext->VSSetConstantBuffers(
		0,
		1,
		m_constantBuffer.GetAddressOf()
		);

}

void CubeRenderer::RenderParticleShader()
{	
	// Set the vertex input layout.
	m_d3dContext->IASetInputLayout(m_inputLayout.Get());

    // Set the vertex and pixel shaders that will be used to render this triangle.
    m_d3dContext->VSSetShader(
		m_vertexShader.Get(),
		nullptr,
		0
		);

	m_d3dContext->PSSetShader(
		m_pixelShader.Get(),
		nullptr,
		0
		);

	auto samplerState = m_commonStates->LinearWrap();
    m_d3dContext->PSSetSamplers(0, 1, &samplerState);

	// Set the sampler state in the pixel shader.
	//m_d3dContext->PSSetSamplers(0, 1, &m_sampleState);

	// Render the triangle.
	m_d3dContext->DrawIndexed(m_indexCount, 0, 0);
}

void CubeRenderer::RenderBuffers()
{
	// Set vertex buffer stride and offset.
    unsigned int stride = m_sizeVertexType; 
	unsigned int offset = 0;
    
	// Set the vertex buffer to active in the input assembler so it can be rendered.
	m_d3dContext->IASetVertexBuffers(0, 1, m_vertexBuffer.GetAddressOf(), &stride, &offset);

    // Set the index buffer to active in the input assembler so it can be rendered.
    m_d3dContext->IASetIndexBuffer(m_indexBuffer.Get(), DXGI_FORMAT_R16_UINT, 0);

    // Set the type of primitive that should be rendered from this vertex buffer.
    m_d3dContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}

VertexShader

VertexShader

cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
	//matrix model;
	matrix view;
	matrix projection;
};

struct VertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
	float4 color : COLOR;
};

struct PixelInputType
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
	float4 color : COLOR;
};

PixelInputType main(VertexInputType input)
{
    PixelInputType output;    
	// Change the position vector to be 4 units for proper matrix calculations.
    input.position.w = 1.0f;

	// Calculate the position of the vertex against the world, view, and projection matrices.
    //output.position = mul(input.position, model);
    output.position = mul(input.position, view);
    output.position = mul(output.position, projection);
    
	// Store the texture coordinates for the pixel shader.
	output.tex = input.tex;
    
	// Store the particle color for the pixel shader. 
    output.color = input.color;

    return output;
}




推荐答案

让你的方块看起来像你需要的方块设置与屏幕宽高比相匹配的投影矩阵。

To get your squares to look like squares you need to set a projection matrix that matches the aspect ratio of your screen.


这篇关于在DirectX中渲染粒子的正方形的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆