こういうやつをOpenGLで書けないかやってみました。
ちなみにOpenGLはopenFrameworks上で直接叩いてます。y軸がOpenGLとは逆なので注意です。
JGraphics.h
メンバ関数ポインタとしてStickをtypedefしています。下図から分かるとおり6つのパーツ(これをスティックと呼びます)から数字は成り立っています。このスティックは横と縦のパーツからなりたっているので、それぞれ描画するdrawVStickとdrawHStickを与えます。
#ifndef JGRAPHICS_H_ #define JGRAPHiCS_H_ #include "ofMain.h" #define DIGIT_PARTS_NUM 7 namespace jonki { class JGraphics { public: JGraphics(void); ~JGraphics(void); // // (略) // void drawNumber(int num, float scale); ); typedef void (JGraphics::*Stick)(); private: void drawVStick(); void drawHStick(); private: // // (略) // Stick sticks[DIGIT_PARTS_NUM]; ofPoint moves[DIGIT_PARTS_NUM]; unsigned char NUM_PAT[10]; }; } #endif
JGraphics.cpp
まずsticksに上記図に対応するよう縦か横のdraw関数を与えます。次にこの数字の順番で記述するため、glTranslatef用の変数も用意します。最後(moves[6])は動く必要がないので、すべて0.fです。NUM_PATには0〜9の対応する数字のパターンを入れています。7個のスティックがtrueかfalseで書けるので下記のように書いています。あとはビット演算でiビット目(i本目)を書くかどうかを0x01と&演算子を取ることで分かります。
JGraphics::JGraphics(void) { sticks[0] = &JGraphics::drawVStick; sticks[1] = &JGraphics::drawVStick; sticks[2] = &JGraphics::drawHStick; sticks[3] = &JGraphics::drawVStick; sticks[4] = &JGraphics::drawVStick; sticks[5] = &JGraphics::drawHStick; sticks[6] = &JGraphics::drawHStick; moves[0] = ofPoint(0.f, 4.f, 0.f); moves[1] = ofPoint(0.f, 4.f, 0.f); moves[2] = ofPoint(3.5f, -4.f, 0.f); moves[3] = ofPoint(0.f, -4.f, 0.f);; moves[4] = ofPoint(-3.5f, 0.f, 0.f); moves[5] = ofPoint(0.f, 4.f, 0.f); moves[6] = ofPoint(0.f, 0.f, 0.f); NUM_PAT[0] = 0x3f; //0011 1111, //!< 0 NUM_PAT[1] = 0x18; //0001 1000, //!< 1 NUM_PAT[2] = 0x76; //0111 0110, //!< 2 NUM_PAT[3] = 0x7c; //0111 1100, //!< 3 NUM_PAT[4] = 0x59; //0101 1001, //!< 4 NUM_PAT[5] = 0x6d; //0110 1101, //!< 5 NUM_PAT[6] = 0x6f; //0110 1111, //!< 6 NUM_PAT[7] = 0x39; //0011 1001, //!< 7 NUM_PAT[8] = 0x7f; //0111 1111, //!< 8 NUM_PAT[9] = 0x7d; //0111 1101, //!< 9 } // // (略) // void JGraphics::drawNumber(int num, float scale) { glPushMatrix(); glScalef(scale, scale, 0.f); for(int i=0; i<DIGIT_PARTS_NUM; i++) { if((NUM_PAT[num] >> i) & 0x01) { (this->*sticks[i])(); } glTranslatef(moves[i].x, moves[i].y, moves[i].z); } glPopMatrix(); } void JGraphics::drawVStick() { glBegin(GL_POLYGON); glNormal3f(0.f, 0.f, 1.f); glVertex3f(0.5f, 0.f, 0.f); glVertex3f(0.f, 0.5f, 0.f); glVertex3f(0.f, 3.5f, 0.f); glVertex3f(0.5f, 4.f, 0.f); glVertex3f(1.f, 3.5f, 0.f); glVertex3f(1.f, 0.5f, 0.f); glEnd(); } void JGraphics::drawHStick() { glBegin(GL_POLYGON); glNormal3f(0.f, 0.f, 1.f); glVertex3f(0.5f, 0.f, 0.f); glVertex3f(1.f, 0.5f, 0.f); glVertex3f(3.5f, 0.5f, 0.f); glVertex3f(4.f, 0.f, 0.f); glVertex3f(3.5f, -0.5f, 0.f); glVertex3f(1.f, -0.5f, 0.f); glEnd(); }
あとはtestApp.cppとかで呼んであげればこの通り
//!< digit glPushMatrix(); for(int i=0; i<10; i++) { m_gfx.drawNumber(i, 30.f); glTranslatef(200, 0, 0); } glPopMatrix();
いろいろやり方はあると思いますが、今回はちょっと変な方法で書いてみますた。とりあえずコンストラクタ内の設定値宣言が汚いですね、はい。