2012年6月28日木曜日

LINQ to XMLと属性とnullと

最近,LINQ to XMLを使う機会が多い.で,こんな感じのコードを書く.

XDocument document = XDocument.load("foo.xml");
var elements = from e in document.Descendants("bar")
                        where e.Attribute("hoge").Value == "foobar"
                        select e;

すると,適当な属性が無い場合null参照で怒られる.で、こう書き換えていた.


XDocument document = XDocument.load("foo.xml");
var elements = from e in document.Descendants("bar")
                        where e.Attribute("hoge") != null && e.Attribute("hoge").Value == "foobar"
                        select e;

でもこれ冗長だなぁ、と思っていたわけで.調べてみると、文字列へのキャストをした方が良い感じ.

XDocument document = XDocument.load("foo.xml");
var elements = from e in document.Descendants("bar")
                        let hoge = (string)e.Attribute("hoge")
                        where hoge != null && hoge == "foobar"
                        select e;

で、ふと思ったのが、文字列型の変数がnullの場合,比較したら落ちるのかな,と.

string a = null;
string b = "hello";
if(a != b){
    Console.WriteLine("not same");
}

ちゃんと比較できるっぽいので,こうすればいちいちnullチェックいらないんじゃね,ということで

XDocument document = XDocument.load("foo.xml");
var elements = from e in document.Descendants("bar")
                        let hoge = (string)e.Attribute("hoge")
                        where hoge == "foobar"
                        select e;

と,ここにたどり着いた.

2012年6月21日木曜日

OpenGL事始め3

背景を塗りつぶしたら,次は点でも表示してみよう.

// main.cpp
#include <GLUT/glut.h>

void display();

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("");
    glutDisplayFunc(display);
    glClearColor(0.f, 0.f, 1.f, 1.f);
    glutMainLoop();

    return 0;
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    // 点を描画
    glBegin(GL_POINTS);
    {
        glVertex2f(0.f, 0.f);
    }
    glEnd();
    glFlush();
}

glBegin(描画方法)からglEnd()の間に点を描画したい座標をglVertex2f()で指定してやると,点が描画される.この場合,中心に白い点が描画される.ただし,凄く小さくて分かりづらい.

そこで,少しサイズを大きくしてみる.サイズの指定は,glPointSize();

// main.cpp
#include <GLUT/glut.h>

void display();

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("");
    glutDisplayFunc(display);
    glClearColor(0.f, 0.f, 1.f, 1.f);
    glutMainLoop();

    return 0;
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    // 点のサイズを指定
    glPointSize(32.f);
    glBegin(GL_POINTS);
    {
        glVertex2f(0.f, 0.f);
    }
    glEnd();
    glFlush();
}

四角くでかい点が出る.ちなみに,このglPointSizeの位置をBeginとEndの間に持ってきても上手く動かない.更に点に丸みを付けてみる.glEnableにGL_POINT_SMOOTHという引数を渡すだけ.

// main.cpp
#include <GLUT/glut.h>

void display();

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("");
    glutDisplayFunc(display);
    glClearColor(0.f, 0.f, 1.f, 1.f);
    glutMainLoop();

    return 0;
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glEnable(GL_POINT_SMOOTH);
    glPointSize(32.f);
    glBegin(GL_POINTS);
    {
        glVertex2f(0.f, 0.f);
    }
    glEnd();
    glFlush();
}

OpenGL事始め2

コードは書きつつも,アウトプットが無さ過ぎなのでちょっと書いておく.

OpenGL事始め1で書いたコードに追加する感じで.

背景を塗りつぶす
だいたいの入門書で取り合えず背景を特定の色で塗りつぶす方法が最初に紹介されている気がする.OpenGLだと,glClear関数を呼び出す.描画関係の処理はglutDisplayFunc()に渡した関数の中に書く.

// main.cpp
#include <GLUT/glut.h>

void display();

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("");
    glutDisplayFunc(display);
    glutMainLoop();

    return 0;
}

void display()
{
    // 色バッファを指定した色で埋める
    glClear(GL_COLOR_BUFFER_BIT);

    // 描画コマンド実行指示
    glFlush();
}

glClear関数は,いくつかのビットフラグになっている定数を指定することで,その定数で指定されたバッファの内容を指定された値で埋めてくれる.今回の場合,色が保存されているバッファを指定した色で埋めている.

最後のglFlush関数は呼び出しておかないと,描画が実行されなかったり.

glClearのデフォルト値は,RGBAで(0, 0, 0, 0)になっているので,何も指定しないと画面が黒になる.
色を指定する場合は,次のようにglClearColorにRGBAを指定する.

// main.cpp
#include <GLUT/glut.h>

void display();

int main(int argc, char * argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("");
    glutDisplayFunc(display);
    // 青色で塗りつぶすようにする
    glClearColor(0.f, 0.f, 1.f, 1.f);
    glutMainLoop();

    return 0;
}

void display()
{
    // 色バッファを指定した色で埋める
    glClear(GL_COLOR_BUFFER_BIT);

    // 描画コマンド実行指示
    glFlush();
}

R(赤),G(緑),B(青),A(アルファ)を0.0fから1.0fの範囲で指定する.

ちなみに,glClearColorの位置をglutCreateWindowの前にすると落ちる.