はかせのラボ

私の頭の中を書いていく雑記ブログです

プログラミング 複数テクスチャ使ったインスタンシングがわからねぇ・・・orz

あいさつ

どうも、はかせです。
今回は以前作った弾幕シューティングを改造しようとして詰まった話です。

改造しようと思った理由

理由はこのツイートをご覧ください。

今の私のすべてがこのツイートに凝縮されています。
それでは今回はこの辺でノシ


・・・・・
とはいきませんねw
ちゃんと説明します。

前回までである程度c++xmlを扱うノウハウを得ました。
なので実際に使ってみようと思ったわけです。

頭の中から妄想で状況とデータを出してもいいんですが、
どうせなら以前作った弾幕シューティングを改造してみようと思ったわけです。
(クオリティがお察しだったからね)
hakase0274.hatenablog.com


それでどうせ改造するなら徹底的にってことで、
インスタンシングも使ってみようと思ったわけです。
弾幕ですから効果絶大でしょうしね。

ただここで問題が発生します。
私が前やったインスタンシングは
プリミティブもしくは単一テクスチャを増産するものでした。

なのでテクスチャが一種類なら問題ないんですが、
複数扱うとなると色々うまくいきません(´;ω;`)

とりあえず愚痴るだけじゃ仕方ないんで
今の進捗を。
まずは一種類のテクスチャをインスタンシングです。

void DXManager::RenderInstancing()
{
	mDeviceContext->VSSetShader(mVertexShader.Get(), NULL, 0);
	mDeviceContext->PSSetShader(mPixelShader.Get(), NULL, 0);
	// パラメータの受け渡し
	D3D11_MAPPED_SUBRESOURCE pdata;
	mDeviceContext->Map(mPerInstanceBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &pdata);
	PerInstanceData* instanceData = (PerInstanceData*)(pdata.pData);
	float defaultYPos = 1.5f;
	float offset = 0.11f;
	int oneLineNum = 10;
	for (int i = 0; i < mInstanceNum ; i++)
	{
		//とりあえずループ変数使って移動
		float xPos = i % oneLineNum * offset - 2.0f;
		float yPos = defaultYPos - (i / oneLineNum * offset);
		XMMATRIX move = XMMatrixTranslation(xPos, yPos, 1.0f);
		//行列情報をセット
		instanceData[i].matrix = XMMatrixTranspose(mScale * mRotation * move * mView * mProj);
		//色情報をセット
		instanceData[i].color = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
	}
	mDeviceContext->Unmap(mPerInstanceBuffer.Get(), 0);
	mDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
	mDeviceContext->VSSetShaderResources(0, 1, mShaderResourceView.GetAddressOf());
	ID3D11ShaderResourceView* srv[] = { mShaderResourceView.Get() ,mTextureShaderResourceView1.Get()};
	mDeviceContext->PSSetShaderResources(0, 2,srv);
	// 描画実行
	mDeviceContext->DrawIndexedInstanced(mDrawNum, mInstanceNum, 0, 0, 0);
}

以前と違うのはテクスチャ用のShaderResourceViewが追加されてってとこですね。
f:id:hakase0274:20190624230817p:plain
問題ありません。

では二種類目のテクスチャを用意して
その隣にある領域に出してみたいです。

void DXManager::RenderInstancing()
{
       //・・・さっきのコード省略
	mDeviceContext->Map(mPerInstanceBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &pdata);
	for (int i = 0; i < mInstanceNum; i++)
	{
		//とりあえずループ変数使って移動
		float xPos = i % oneLineNum * offset - 1.0f;
		float yPos = defaultYPos - (i / oneLineNum * offset);
		XMMATRIX move = XMMatrixTranslation(xPos, yPos, 1.0f);
		//行列情報をセット
		instanceData[i].matrix = XMMatrixTranspose(mScale * mRotation * move * mView * mProj);
		//色情報をセット
		instanceData[i].color = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
	}
	mDeviceContext->Unmap(mPerInstanceBuffer.Get(), 0);
	mDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
	mDeviceContext->VSSetShaderResources(0, 1, mShaderResourceView.GetAddressOf());
	ID3D11ShaderResourceView* srv2[] = { mShaderResourceView.Get() ,mTextureShaderResourceView2.Get() };
	mDeviceContext->PSSetShaderResources(0, 2, srv2);
	// 描画実行
	mDeviceContext->DrawIndexedInstanced(mDrawNum, mInstanceNum, mDrawNum, 0, 0);
}

f:id:hakase0274:20190624230911p:plain
そのまんまスライドしちゃった!?

・・・・・・・・・
まぁシェーダーに渡していたバッファを
Map/Unmapで直接書き換えているのでわからなくはないですが、
これはなかなかきついですね・・・

あとがき

今回は以前作った弾幕を改造しようと
最近勉強したことをつぎ込もうとしたら
勉強不足だった話でした。

やっぱ実際に使ってみようとしないと
実際にハマる穴に落ちないですねw

またあーでもないこーでもないって頭悩ましつつ、
色んなサイトめぐって解決策探します。

それでは今回はこの辺でノシ