上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
私はプログラマで6年目なのですが、
前々から思うことは数学勉強しておけば良かったーーーってことです。

プログラムも色々ありますけど、グラフィックに携わるプログラマーは数学大事です。

で、今日の話は数学ができればプログラマーとして一生安泰ということ。

正直、プログラムなんて1年もあれば自分で工夫できるレベルまで上達するものです。

プログラムなんて極端に言えばコピペの集合体みたいなもので、
コピペができればどんなプログラムも書けます。

3Dプログラマの価値は数学の知識にある。

プログラマを仕事にしたいって考える人はプログラムより、数学勉強するべし。
現在、C言語から始めてC++, C#, JavaScriptくらいは使えますが、
1言語を使えれば何をコピペするかの違いだけであとはおんなじ。

で、プログラマに必要な数学の知識は非常に少ないんです。





なんと「3つ」

3つだけ

3つ極めたら一生食っていけるんです。
どう?簡単でしょ?

グラフィックプログラマって、
3次元空間で物体の座標や回転角度を計算できればお金が貰える超簡単仕事()です。

必要な3つとは

1.四則演算
2.ベクトル
3.行列

これだけ

四則演算は足し算、引き算、掛け算、割り算のことです。
小学校を卒業したら極めてますので、次にいきましょう。

↓↓

残りの、
「ベクトル」と「行列」を勉強すれば3D空間で物体を自由に制御できます。

なぜならOpenGL、DirectX、Unityといった有名ライブラリがそのようにできてるから。


例えば、ある方向に物体を移動させたいって処理は

P = pt + vec * t

これで、ある地点(pt)からある方向(vec)へ一定距離(t)移動させた座標(P)が計算できます。

パッと見、意味不明ですが、ちょっと考えてみてください

こんな式と、その他の似たような式を理解するだけで一生食っていけるんです

今は意味がわからなくても半年もあれば理解できると思いません?

ネットで「線形台数 入門」とかでググれば超わかりやすいサイトがいくつも出ます。

あ、数式がドヤ顔で羅列されてるサイトは更新者が物事を伝えることに向いていないコミュ章なので見るのやめましょう。

こんなに楽な仕事は他にないですよ

以上!
OpenTKにてポリゴン表示を行う場合の頂点カラー表示方法


if (this.VboBufferId[0] != 0)
{
GL.DeleteBuffers(1, this.VboBufferId);
}

GL.GenBuffers(1, this.VboBufferId);

Polygon[] polygons = this.Polygons;
this.VboArray = new float[polygons.GetLength(0) * 9 * 3];

for (int polygonInd = 0; polygonInd < polygons.GetLength(0); polygonInd++)
{
// vertex 0
this.VboArray [polygonInd * 9 * 3] = polygons[polygonInd].VertexC.X;
this.VboArray [(polygonInd * 9 * 3) + 1] = polygons[polygonInd].VertexC.Y;
this.VboArray [(polygonInd * 9 * 3) + 2] = polygons[polygonInd].VertexC.Z;
this.VboArray [(polygonInd * 9 * 3) + 3] = polygons[polygonInd].NormalVectC.X;
this.VboArray [(polygonInd * 9 * 3) + 4] = polygons[polygonInd].NormalVectC.Y;
this.VboArray [(polygonInd * 9 * 3) + 5] = polygons[polygonInd].NormalVectC.Z;
this.VboArray [(polygonInd * 9 * 3) + 6] = polygons[polygonInd].Color.X;
this.VboArray [(polygonInd * 9 * 3) + 7] = polygons[polygonInd].Color.Y;
this.VboArray [(polygonInd * 9 * 3) + 8] = polygons[polygonInd].Color.Z;

// vertex 1
this.VboArray [(polygonInd * 9 * 3) + 9] = polygons[polygonInd].VertexB.X;
this.VboArray [(polygonInd * 9 * 3) + 10] = polygons[polygonInd].VertexB.Y;
this.VboArray [(polygonInd * 9 * 3) + 11] = polygons[polygonInd].VertexB.Z;
this.VboArray [(polygonInd * 9 * 3) + 12] = polygons[polygonInd].NormalVectB.X;
this.VboArray [(polygonInd * 9 * 3) + 13] = polygons[polygonInd].NormalVectB.Y;
this.VboArray [(polygonInd * 9 * 3) + 14] = polygons[polygonInd].NormalVectB.Z;
this.VboArray [(polygonInd * 9 * 3) + 15] = polygons[polygonInd].Color.X;
this.VboArray [(polygonInd * 9 * 3) + 16] = polygons[polygonInd].Color.Y;
this.VboArray [(polygonInd * 9 * 3) + 17] = polygons[polygonInd].Color.Z;

// vertex 2
this.VboArray [(polygonInd * 9 * 3) + 18] = polygons[polygonInd].VertexA.X;
this.VboArray [(polygonInd * 9 * 3) + 19] = polygons[polygonInd].VertexA.Y;
this.VboArray [(polygonInd * 9 * 3) + 20] = polygons[polygonInd].VertexA.Z;
this.VboArray [(polygonInd * 9 * 3) + 21] = polygons[polygonInd].NormalVectA.X;
this.VboArray [(polygonInd * 9 * 3) + 22] = polygons[polygonInd].NormalVectA.Y;
this.VboArray [(polygonInd * 9 * 3) + 23] = polygons[polygonInd].NormalVectA.Z;
this.VboArray [(polygonInd * 9 * 3) + 24] = polygons[polygonInd].Color.X;
this.VboArray [(polygonInd * 9 * 3) + 25] = polygons[polygonInd].Color.Y;
this.VboArray [(polygonInd * 9 * 3) + 26] = polygons[polygonInd].Color.Z;
}

GL.EnableClientState(ArrayCap.VertexArray);
GL.EnableClientState(ArrayCap.NormalArray);
GL.EnableClientState(ArrayCap.ColorArray);

GL.DisableClientState(ArrayCap.TextureCoordArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, this.VboBufferId[0]);

GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(this.VboArray.Length * sizeof(float)), this.VboArray, BufferUsageHint.StaticDraw);
}

GL.BindBuffer(BufferTarget.ArrayBuffer, this.VboBufferId[0]);

// set strides/offsets
GL.VertexPointer(3, VertexPointerType.Float, 9 * sizeof(float), 0);
GL.NormalPointer(NormalPointerType.Float, 9 * sizeof(float), 3 * sizeof(float));

GL.ColorPointer(3, ColorPointerType.Float, 9 * sizeof(float), 6 * sizeof(float));

GL.Enable(EnableCap.ColorMaterial);
GL.ColorMaterial(MaterialFace.Front, ColorMaterialParameter.Diffuse);

GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 32);
GL.ShadeModel(ShadingModel.Smooth);

GL.Enable(EnableCap.Normalize);
GL.DrawArrays(BeginMode.Triangles, 0, this.VboArray.Length / 9);
GL.Disable(EnableCap.Normalize);

//GL.DisableClientState(ArrayCap.ColorArray);
GL.Disable(EnableCap.ColorMaterial);
WPF 押しっぱなしで動作するボタン

RepeatButton

イベント発生の間隔は「Interval」プロパティ(ms)で設定可能。

以上!



今作っているプログラムで、
ボタンを押しっぱなしで動作させたかったので調べていたらそのままのボタンあってワロタ

危うくボタンダウンイベントでタイマー起動
ボタンアップイベントでタイマー終了
タイマーイベントで動かしたい処理(funcA)
なんてアホなことやるところだったぜ。

これやると押した瞬間~Intervalの時間までイベント発生しないので
違和感あるようになるし、
ダウンイベント~タイマー起動までに一回funcA呼ぶか?なんて
ややこしいことになるからやりたくなさすぎた。
C# WPFのキーイベント処理

キー入力処理を行う際のコードって


public void KeyDown(object sender, KeyEventArgs e)
{
if(e.Key == Key.Z)
{
// 処理
}
}


こんな感じですよね。


でもこれだと不十分で、
IMEが「かな」入力だったりした際にZキーを押しても反応しません。

デバッグで見るとe.Keyには「ImeProcessed」が入ってます。
変わりにe.ImeProcessedKeyに「Z」が入ってます。

逆にIMEが非有効の場合にはe.ImeProcessedKeyは「None」が入ってます。

ここら辺を使って処理できそうです。


Key inputKey;
if (e.ImeProcessedKey != Key.None)
{
inputKey = e.ImeProcessedKey;
}
else
{
inputKey = e.Key;
}

if (inputKey == Key.Z)
{
// 処理
}


こうしておけば対応できます。

WinFormにはe.KeyCodeって便利そうなプロパティが用意されてるのでこれを使えば簡単にできそうです(未確認)。


まぁ、仕様の問題でもありまして、
「半角のみ対応」って一言書けば終わりな気もしますし、世のゲームは半角のみが多いですよね。

結構慣れてるユーザは無意識に半角入力にしたりしますし、私もこのタイプのユーザです。
DLLImportの多言語化について

ちょっとハマったのでメモ。

現在、C#のアプリを作成してましてフォルダ複数選択ダイアログを自作しました。

C#単体では「マイコンピュータ」のような特殊なフォルダ?とか、
フォルダのアイコンとか取得できないのでShellAPIを使うことになります。

で、作成できたものの、
フォルダ名に日本語にない文字がある場合、化けてしまったのでその対応をしました。
たとえば中国OSで上記問題が起こりました。

環境をまとめると
ベース:C#
多言語したい対象 : C++(DLLImportで使用)

この場合はsetlocaleとかCurrentInfoとかで設定できません。

前置きが長くなりましたが、解決策。

DLLImportに文字コードを設定できるプロパティ CharSet がありますのでこれを設定すればOK。

具体的にはこんな書き方です。

[DllImport("shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(IntPtr pIDL, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);

CharSet.Autoは実行しているOSによって自動的に選択されるプロパティ。
ちなみに何も指定しない場合は、コンパイルした言語になるっぽいです。バグってた時だとAnsiかな。


あと注意するのはこの関数で使っている構造体などなども設定する必要があります。

上記の例だと「SHFILEINFO」ですね。

構造体の前に「StructLayout」で設定します。

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}

こんな感じ。


ShellAPIなんか滅多に使わないですけど、使わないからこそ情報も少ない、
よって詰むので一応。
advertisement


プロフィール

とりにく

Author:とりにく
ゲーム好きなプログラマーやってます。

使用可能言語:C,C++,C#,WPF,JavaScript,Cuda
使用可能開発環境:VisualStudio2005-2013,Unity,CodeWarrior

リンクフリーです
相互リンクなどはこちら↓までかコメント欄にでもよろしくです。
skymail_tt@yahoo.co.jp

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