忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


アジャイルでXNAゲーム開発

"XNA Game Programming"を2章読んだのですが、(全部で14章)
著者のベンジャミンさんはかなりアジャイルをプッシュしているようです。

しょっぱなの簡単なゲームのサンプル(Pongゲーム)から
ユニットテストを行っています。

ユニットテストといってもNUnitなんかを使うわけではなく、
ただ単にある動作をさせるメソッドを作って目で直接チェックします。
(まぁグラフィックスが絡むと自動テストはかなり難しくなりますからね。)

例えば、画面にメニューを表示させたいのなら、
メニューを出すTestMenuSpritesというメソッドを作り、
それをMainメソッドから通常のコードの代わりに呼び出します。
上手くメニューが表示されたかどうかは自分の目でチェックします。

この方法が単に行き当たりばったりプログラミングよりも優れているのは、
テストしたいことを直接テストできると言う点です。
この本ではボールの衝突チェックのユニットテストの時に真価が発揮されています。

もし行き当たりばったりのプログラミングをしていたのなら、
メニューからスタートし、ゲームを始め、
実際にラケットでボールを弾いて衝突が
上手くいっているか確かめることになるでしょう。
しかしこれでは面倒です。

ここでチェックしたいのはボールの衝突だけであって、
メニューやゲームの開始ではないからです。
それに衝突と一口に言ってもラケットとの衝突、横壁との衝突、縦壁との衝突など
色々あります。
ボールがきちんとチェックできる状態になるまで時間がかかるかもしれません。

この本では、ユニットテストを行うメソッドの中で、
ゲームを直ちにテストできる状態にしています。
メニューを初めに表示するのではなく、もう既にゲームが始まった状態にし、
そしてボールの位置は、キーボードの状態によって
壁の近くに配置できたりするのです。

これなら比較的簡単に結果を確かめることが出来るでしょう。

グラフィックスが絡むと自動テストは難しくなりますが、
自動テストと同じくらい簡単なテストを作ることは出来るのです。

拍手[0回]

PR

RenderStateのプロパティ

どうも紛糾してきたのでMicrosoft.Xna.Framework.Graphics.RenderStateのプロパティについてまとめたいと思います。

1.Alpha Blending
        public bool AlphaBlendEnable { get; set; }
        public Blend SourceBlend { get; set; }
        public Blend DestinationBlend { get; set; }
        public BlendFunction BlendFunction { get; set; }
        public Color BlendFactor { get; set; }

        public bool SeparateAlphaBlendEnabled { get; set; }
        public Blend AlphaSourceBlend { get; set; }
        public Blend AlphaDestinationBlend { get; set; }
        public BlendFunction AlphaBlendOperation { get; set; }

2.Alpha Testing
        public bool AlphaTestEnable { get; set; }
        public CompareFunction AlphaFunction { get; set; }
        public ReferenceAlpha { get; set; }


3.Point Sprite
        public bool PointSpriteEnable { get; set; }
        public float PointSize { get; set; }
        public float PointSizeMax { get; set; }
        public float PointSizeMin { get; set; }

4.Culling
        public CullMode CullMode { get; set; }

5.Depth Buffering
        public DepthBufferEnable { get; set; }
        public CompareFunction DepthBufferFunction { get; set; }
        public bool DepthBufferWriteEnable { get; set; }

        public float DepthBias { get; set; }
        public float SlopeScaleDepthBias { get; set; }

6.Fog
        public bool FogEnable { get; set; }
        public float FogStart { get; set; }
        public float FogEnd { get; set; }
        public Color FogColor { get; set; }
        public float FogDensity { get; set; }
        public FogMode FogTableMode { get; set; }
        public FogMode FogVertexMode { get; set; }
        public bool RangeFogEnable { get; set; }
        
7.Outline and Fill
        public FillMode FillMode { get; set; }
        
8.Stencil Buffer
        public bool StencilEnable { get; set; }
        public int ReferenceStencil { get; set; }
        public StencilOperation StencilDepthBufferFail { get; set; }
        public StencilOperation StencilFail { get; set; }
        public CompareFunction StencilFunction { get; set; }
        public int StencilMask { get; set; }
        public StencilOperation StencilPass { get; set; }
        public int StencilWriteMask { get; set; }
        public bool TwoSidedStencilMode { get; set; }
        public StencilOperation CounterClockwiseStencilDepthBufferFail { get; set; }
        public StencilOperation CounterClockwiseStencilFail { get; set; }
        public StencilOperation CounterClockwiseStencilFunction { get; set; }
        public StencilOperation CounterClockwiseStencilPass { get; set; }

9.Scissor Test
        public bool ScissorTestEnable { get; set; }

10.MultiSample
        public bool MultiSampleAntiAlias { get; set; }
        public int MultiSampleMask { get; set; }

11.Color Write Channels
        public ColorWriteChannels ColorWriteChannels { get; set; }
        public ColorWriteChannels ColorWriteChannels1 { get; set; }
        public ColorWriteChannels ColorWriteChannels2 { get; set; }
        public ColorWriteChannels ColorWriteChannels3 { get; set; }

12.Texture Wrapping
        public TextureWrapCoordinates Wrap0 { get; set; }
        public TextureWrapCoordinates Wrap1 { get; set; }
        public TextureWrapCoordinates Wrap2 { get; set; }
        public TextureWrapCoordinates Wrap3 { get; set; }
        public TextureWrapCoordinates Wrap4 { get; set; }
        public TextureWrapCoordinates Wrap5 { get; set; }
        public TextureWrapCoordinates Wrap6 { get; set; }
        public TextureWrapCoordinates Wrap7 { get; set; }
        public TextureWrapCoordinates Wrap8 { get; set; }
        public TextureWrapCoordinates Wrap9 { get; set; }
        public TextureWrapCoordinates Wrap10 { get; set; }
        public TextureWrapCoordinates Wrap11 { get; set; }
        public TextureWrapCoordinates Wrap12 { get; set; }
        public TextureWrapCoordinates Wrap13 { get; set; }
        public TextureWrapCoordinates Wrap14 { get; set; }
        public TextureWrapCoordinates Wrap15 { get; set; }


む・・・・・・{ get; set; }はいらなかったかな・・・・・・
セットできないRenderStateに意味は無いわけですし、
セットできてゲットが出来ないプロパティと言うのもあまりないですからね。

       

拍手[0回]


XNA本

注文していたXNAの本が届きました

Racing GameのBenjamin Nitschkeさんの書いた
"XNA Game Programming"
と、別の人の"XNA GAME STUDIO Creator's Guide"です。

まだパラパラめくっただけですが、"XNA Game Programming"のほうは
HLSLをバリバリ使っているようです。
著者のベンジャミンさんは「SimpleEffectは柔軟性がないから使わない」
みたいなことを言っています。
XNAではじめてゲームプログラミングを始める人にとっては拷問ですが、
「かんたんXNA」もそろそろHLSLに入ろうかと思っていたところなの
でかえって都合がよかったかもしれません。

(なんだかXNAでは、デザインパターンをふんだんに使ったHelloWorld
みたいなことが頻発しているような気がしなくもありません。)

これから読むつもりですが、まぁ、ともかく楽しみです。

拍手[0回]


かんたんXNA 間違い修正

かんたんXNAを見直していたらいくつか間違いを見つけたので
直しておきました。
(これでどつぼにはまった方にはすいません)

まず、
誤: content.Load(...
正: content.Load<Texture2D>(...
です。

コードの時点では合っていたのですが、
ブログの記事にするときに
<Texture2D>

<texture2d></texture2d>
になってしまいました。
タグであると解釈されてしまったんですね。

同様に
誤: drawUserPrimitives(...
正: drawUserPrimitives<....>(...
です。

こういう間違いがあるから
書いた記事は後から何度か見直ししなければいけませんね。

拍手[0回]


Java 列挙型

久々にJavaを使っていると(JOGL)、
列挙型の使い方がわからなくなったので
今後のためメモしておきます。

まず文脈を話しておくと、
Java用のOpenGL(JOGL)を使っていたのですが、
この定数が汚いんですね。

多くの定数がGLというクラスの中に定義されていて、
しかもその定数の種類というのが、
プリミティブのタイプもカリングモードも
行列の種類もアルファブレンディングも
なにもかもごっちゃになっています。

//プリミティブのタイプを表す定数
GL.GL_POINTS
GL.GL_LINES
GL.GL_LINE_STRIP
GL.GL_LINE_LOOP
GL.GL_TRIANGLES
GL.GL_TRIANGLE_FAN
...
//行列
GL.GL_PROJECTION
GL.GL_MODELVIEW

...(以下略)


ごちゃごちゃです。
まず第一、"GL"をなぜ2度も書かなければならないのか
そこが不条理です。

そして第二に、目的の異なる定数を1つのクラスに
大量に詰め込むのはよくありません。
どのくらい大量かというと、このくらいです。
もうわけがわかりません。

こんなときには列挙型を使って用途別に分別すべきです。
(そしてGLクラス全体のラッパーを作り始めたのですが、
ここではあまり関係ありません)

とりあえず最初は描画する図形のタイプを
表す定数を列挙型にすることにしました。

しくじってしまったのはここで、
C#のようなやり方をしてはいけません

Compile Error!

import javax.media.opengl.*;

public enum PrimitiveType {
	Points = GL.GL_POINTS,
	Lines = GL.GL_LINES,
	LineStrip = GL.GL_LINE_STRIP,
	LineLoop = GL.GL_LINE_LOOP,
	Triangles = GL.GL_TRIANGLES,
	TriangleFan = GL.GL_TRIANGLE_FAN,
	Quads = GL.GL_QUADS,
	QuadStrip = GL.GL_QUAD_STRIP,
	Polygon = GL.GL_POLYGON
}

正しくはこうです。
(javaのコードとして記法に問題がありますが、
まあほうっておきましょう(PointsではなくPOINTS))

import javax.media.opengl.*;

public enum PrimitiveType {
	Points(GL.GL_POINTS),
	Lines(GL.GL_LINES),
	LineStrip(GL.GL_LINE_STRIP),
	LineLoop(GL.GL_LINE_LOOP),
	Triangles(GL.GL_TRIANGLES),
	TriangleFan(GL.GL_TRIANGLE_FAN),
	Quads(GL.GL_QUADS),
	QuadStrip(GL.GL_QUAD_STRIP),
	Polygon(GL.GL_POLYGON);
	
	private int value;
	
	PrimitiveType(int value){
		this.value = value;
	}
	
	public int value(){
		return value;
	}
}

Javaでは = ではなく () を使うんですね・・・
知りませんでした。
そしてその値がコンストラクタの引数となるようです。
その値をわざわざ保存して、ゲッターで手に
入れられるようにしなければなりません。

そして、さらにC#と違う点として、値を複数指定することも出来ます。
例えば、サンの解説によると、太陽系の各惑星の列挙型を作ったとすれば、
質量と半径の両方を列挙型の値とすることができます。

このことから、Javaの列挙型はC#のものよりも柔軟であるといえるでしょう。
それがいいほうに向かうか悪い方に向かうかはわかりませんが。


拍手[0回]