C#は電気羊の夢を見るか?(引っ越し中)

dtiブログが閉鎖とのことでhttp://tanocs.blog.fc2.com/へ引っ越します。

SlimDX.D3D9を使いGPUで描画した結果をCPUで取得する

相変わらず海外を含めてサンプルが見つからない。

SlimDXでGPGPUをDX9のまま実装するため
描画済みのテクスチャを取得する方法を置いとく

描画メソッド内に以下の内容を実行すると、取得ができる。

テスト用のメソッドなので、ビットマップの保存や、
巨大な配列の宣言とかは適宜修正してくりゃれ。


//レンダーターゲットを用意する
renderTexture = new Texture(device, this.ClientSize.Width, this.ClientSize.Height, 1, Usage.RenderTarget, Format.X8R8G8B8, Pool.Default);
renderSurface = renderTexture.GetSurfaceLevel(0);

//レンダーターゲットを保存する
oldRenderSurface = device.GetRenderTarget(0);

//レンダーターゲットを変更する
device.SetRenderTarget(0, renderSurface);

//画面を初期化
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
device.BeginScene();

//データを流しこんで描画
device.SetStreamSource(0, vertices, 0, Marshal.SizeOf(typeof(Vertex)));
device.VertexDeclaration = vertexDecl;
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);

//レンダーターゲットを元に戻す
device.SetRenderTarget(0, oldRenderSurface);
oldRenderSurface.Dispose();

//ストリームを用意
DataStream stream = Texture.ToStream(renderTexture, ImageFileFormat.Bmp); //ファイルストリームと等価

//ビットマップとして流しこむ
Bitmap bmp = (Bitmap)Bitmap.FromStream(stream, false, false);

//内容を保存して確認
bmp.Save("test.bmp", System.Drawing.Imaging.ImageFormat.Bmp);

//直接バイト型として参照も可能
byte[] bs = new byte[stream.Length / sizeof(byte)];
stream.Read(bs, 0, bs.Length);

device.EndScene();
device.Present();



はっきり言って暗中模索のなか、どうにか実行できているレベルなので、
このままでは問題が起こる可能性が多分にある。

メモリリークの可能性や、その他何か気づいた点があったら、
遠慮なくコメントからツッコミをお願いします。


蛇足:
国内のサンプルは何故かテクスチャを
一生懸命BitmapクラスやらImageクラスからメモリ通して作ってるけど、
なんで
Texture tex = Texture.FromFile(device, filePath);
を使わないんじゃろうか・・・

低速であっても、どうせ初期化の一回きりの処理だし、
気にならないと思うんだけど、何か理由があるんだろうか・・・
このエントリーをはてなブックマークに追加
LINEで送る

Windows7でWindowsXPのペイントを使う

かなり高機能なったWindows7のmspaint

しかし、使い慣れない部分も多く、あの機能がなくなったなぁ・・・
と思うことも多い。
なんか、この行はどこかで見たような気がするが気にしない。

そこで、使わなくなった正規XPのCDを破棄したり、中古でPCショップに渡さず、
XPをインストールしていた時にバックアップをしたmspaint.exeさんを
Windows7マシンにコピーし実行しましょう。

すると、ちゃんと懐かしのあの画面が出てきます。
機能的な制限もなく、exe一つで簡単に実行できます。


HDDがクラッシュして使わなくなった古いPCからリカバリCDをもらったりすれば、
権利的にもグレーにはなると思う。

くれぐれも友人のパソコンや学校、職場のパソコンからコピーだけしないように。
ホログラムに輝く正規CDを胸に行うこと。


ちなみにXPのバージョンである5.1は、ほぼそのまま使えるのですが、
2000のバージョンである5.0はjpeg保存ができなくなります、トホホ。
このエントリーをはてなブックマークに追加
LINEで送る

密かなるSlimDX

最近SlimDXを始めた。

んが、しかし。
XNAとぜんぜん使い勝手が違う。
なんていうか、ラップが薄く、”楽”じゃないなぁという感じ。

しかも!なかなかと変な癖があって
Vector3.Transformの戻り値がVector4だったり、
Colorの持ち方がint型だったり、そこかしこに罠が潜んでいる。

そのあまりの違いに、まともにモデルを表示することもままならず、
途方にくれていた。


その原因はとにかくサンプルがない。
情報の殆どは英語と、なかなか敷居が高い。

たかだかインデックスバッファのサンプルを探しても、
どうやら存在しないのだから泣けてくる。

仕方ないのでDirectXのサンプルやらXNAの記憶とかを便りになんとか、
シンプルなIndexBuffer描画サンプルを作成したので、ここに置いておく。



実行結果


using SlimDX;
using SlimDX.Direct3D9;
using SlimDX.Windows;

using System.Runtime.InteropServices;

namespace IndexbufferTest
{
public partial class Form1 : Form
{
Device device;

public struct TestVertex
{
public Vector3 Position;
public Vector3 Normal;
public int Color;
}

VertexElement[] vertexElementsArray = new VertexElement[]
{
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
new VertexElement(0, 24, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0)
};

Vector3[] vectors = new Vector3[] { new Vector3(-1, 0, 0),
new Vector3(0, 1, 0),
new Vector3(1, 0, 0),
new Vector3(0, -1, 0)
};

public Form1()
{
InitializeComponent();

var pp = new PresentParameters();
pp.BackBufferWidth = this.ClientSize.Width;
pp.BackBufferHeight = this.ClientSize.Height;
pp.DeviceWindowHandle = this.Handle;

this.device = new Device(new Direct3D(), 0, DeviceType.Hardware, this.Handle, CreateFlags.HardwareVertexProcessing, pp);
}

public void Run()
{
SlimDX.Windows.MessagePump.Run(this, Draw);
}

protected virtual void Draw()
{
int vertexSize = Marshal.SizeOf(typeof(TestVertex));

VertexBuffer vertexBuffer = new VertexBuffer(device, vectors.Length * vertexSize, Usage.None, VertexFormat.None, Pool.Managed);

var vertexData = new TestVertex[vectors.Length];
for (int i = 0; i < vertexData.Length; i++)
{
vertexData[i].Position = vectors[i];
vertexData[i].Normal = new Vector3(0, 0, -1);
vertexData[i].Color = Color.Gold.ToArgb();
}


IndexBuffer indexBuffer = new IndexBuffer(device, vectors.Length * sizeof(uint) * 3 - 2, Usage.None, Pool.Managed, false);
var indices = new uint[]{0, 1, 2,
0, 2, 3};

device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);
device.SetRenderState(RenderState.Lighting, false);
device.BeginScene();

device.VertexDeclaration = new VertexDeclaration(device, vertexElementsArray);

DataStream vertexBufferStream = vertexBuffer.Lock(0, vectors.Length * vertexSize, LockFlags.None);
vertexBufferStream.WriteRange(vertexData);
vertexBuffer.Unlock();
device.SetStreamSource(0, vertexBuffer, 0, vertexSize);

DataStream indexBufferStream = indexBuffer.Lock(0, indices.Length * sizeof(uint), LockFlags.None);
indexBufferStream.WriteRange(indices);
indexBuffer.Unlock();
device.Indices = indexBuffer;

device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vectors.Length, 0, indices.Length / 3);

device.EndScene();
device.Present();
}
}
}
このエントリーをはてなブックマークに追加
LINEで送る

 | HOME | 

PAGE TOP ▲

Appendix

■春条

■春条

生息地は愛知
車と甘い物が好きな31歳
特技は無限昼寝

MONOからSharpDXを使う
変態的な手法で、
.NET Frameworkを使わずに
ゲーム作りやってます。

Search

Calender

« | 2011-09 | »
S M T W T F S
- - - - 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 -

Twitter

Recent Entries

DTIブログポータルへ
このブログを通報
Report Abuse

利用規約