05
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
   

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

SharpDXへ&DirectX11でのVertexBufferの使い回し@環境依存怖い

現在開発していたライブラリの環境依存の原因が特定できずSharpDXへ移動
DXLib->SlimDX->DirectX直->SharpDXですね。

環境依存その1.文字列の場所がずれる(しかも部分的に…)
環境依存その2.なんかテクスチャが表示されない(部分的に)

もうC++/CLI触りたくない・・・

というわけでSharpDXへ移動しました

で、いろんなサイト見たけど(英語も)VertexBufferをDirectX11で使いまわす方法探すの大変だったのでまとめときます。




管理のクラスだけ…

using SharpDX;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Buffer = SharpDX.Direct3D11.Buffer;

namespace NineTail.Core
{
/// <summary>
/// Bufferに送るための頂点の管理リストです
/// </summary>
/// <typeparam name="T"></typeparam>
public class VerticesList<T>:IEnumerable,IDisposable
where T:struct
{
List<T> vertices;

int typeSize;

/// <summary>
/// 頂点バッファ
/// (毎回Createするのはどう考えても効率が悪い)
/// </summary>
Buffer verticesBuffer;

public bool IsDisposed { get; private set; }

public VerticesList(Device device)
{
vertices = new List<T>();

typeSize = Marshal.SizeOf(typeof(T));

//ダミーデータ突っ込んでバッファ作っておく
BufferDescription desc = new BufferDescription()
{
SizeInBytes = typeSize,
Usage = ResourceUsage.Dynamic,
BindFlags = BindFlags.VertexBuffer,
StructureByteStride = 0,
};
verticesBuffer = new Buffer(
device, 1024 * typeSize, ResourceUsage.Dynamic, BindFlags.VertexBuffer,
CpuAccessFlags.Write, ResourceOptionFlags.None, typeSize);
//verticesBuffer = Buffer.Create<T>(device, new T[1], desc);
}

public void AddVertices(IEnumerable<T> vertices)
{
this.vertices.AddRange(vertices);
}

/// <summary>
/// 頂点データをデバイスに送りつけて実際に描画します。
/// また、頂点座標はクリアされます。
/// </summary>
public void SendVertices(DrawDevice target)
{
int verticesCount = vertices.Count;
if (verticesCount == 0) return;


target.DeviceContext.UpdateSubresource(vertices.ToArray(), verticesBuffer);


//Bufferを使いまわしたいため
//boxの生成速度が遅かった場合更にプリミティブな関数に移動する必要あり
var box = target.DeviceContext.MapSubresource(verticesBuffer, 0, MapMode.WriteDiscard, MapFlags.None);
for (int i = 0; i < vertices.Count; i++)
{
Marshal.StructureToPtr(vertices[i], box.DataPointer + typeSize * i, false);
}
target.DeviceContext.UnmapSubresource(verticesBuffer, 0);


VertexBufferBinding vbb = new VertexBufferBinding(verticesBuffer, typeSize, 0);

target.DeviceContext.InputAssembler.SetVertexBuffers(0, vbb);


target.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;

//あとでIndexで出来るようにしたい
target.DeviceContext.Draw(verticesCount, 0);

vertices.Clear();
}


public IEnumerator GetEnumerator()
{
return vertices.GetEnumerator();
}

public void Dispose()
{

if (verticesBuffer == null)
verticesBuffer.Dispose();
verticesBuffer = null;

IsDisposed = true;

}


}
}


以下解説

ゲームで使うならBufferは毎回毎回作ってたんじゃあ間に合いません(DirectX9の時の経験)
というわけで使いまわそうというお話…

まずBufferをDynamicで使いたいのでそれで作成する必要があります。
ここでつまりましたー

verticesBuffer = new Buffer(
device, 1024 * typeSize, ResourceUsage.Dynamic, BindFlags.VertexBuffer,
CpuAccessFlags.Write, ResourceOptionFlags.None, typeSize);

こんなかんじでDynamicで使うためにはMiscFlagsは0でないとダメっぽいです
ここでバッファ十分に確保しとかないとアウトだと思います。(実際まだバッファが溢れそうな時の挙動を記述してないので…ええ)
構造化バッファじゃないけど気持ち程度にストライド設定してます

あとはMapして書き込めーだけなんですけど
MapFlagsをD3D11_MAP_FLAG_DO_NOT_WAITで指定するとダメっぽいです。

このへんの何を指定すればいいのかってのは結構つまりますねー

いやそれはいいんだけどそろそろ環境依存しないライブラリ作りたいですはい…
あとそろそろベースライブラリコロコロ変えるのやメタラー?)
スポンサーサイト

Comment

Secret

Trackback


この記事にトラックバックする(FC2ブログユーザー)

まとめ【SharpDXへ&DirectX11】

現在開発していたライブラリの環境依存の原因が特定できずSharpDXへ移動DXLib->SlimDX->DirectX直->SharpD

検索フォーム

RSSリンクの表示

リンク

リンクというか個人的によく使うアルゴリズムの解説サイト… C#でなかったりする

ブロとも申請フォーム

この人とブロともになる

QRコード

QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。