OpenSceneGraph用の画像ファイルリーダープラグインの作成

この記事では、OpenSceneGraphのプラグインの作成に焦点を当てます。 このプラグインは、ZSoft CorporationのPCX形式を使用する機能を追加します。 コードは極限まで単純化されており、読み取り機能のみが含まれています。書き込み機能を自分で作成することをお勧めします。 サイトwww.openscenegraph.orgでプラグインのソースコードをダウンロードして、すべてがどのように機能するかを確認できることを理解していますが、ソースコードのフォーマットに少し驚いたので、すべてを整理することにしました。 そして、忘れないように自分用のメモを残してください。



画像



メインクラス



最初に、osgDB :: ReaderWriterクラスの子孫であるクラスを作成する必要があります。 3Dプラグインもこのクラスを使用します。



class ReaderWriterPCX : public osgDB::ReaderWriter { public: ReaderWriterPCX(); const char* className() const; ReadResult readObject(std::istream& fin, const Options* options = 0) const; ReadResult readObject(const std::string& file, const Options* options = 0) const; ReadResult readImage(std::istream& fin, const Options* options = 0) const; ReadResult readImage(const std::string& file, const Options* options = 0) const; WriteResult writeImage(const osg::Image& image, std::ostream& fout, const Options* = 0) const; WriteResult writeImage(const osg::Image& img, const std::string& fileName, const Options* options = 0) const; private: static ReadResult readPCXStream(std::istream& fin); };
      
      





上記のコードからわかるように、これはファイルの読み取りと書き込み、および使用するクラス名とファイル拡張子の設定のためのプラグインの機能の説明です。 残りのコードは提供しません。 記事の最後のリンクまたは別の例のOpenSceneGraphソースコードで確認できます。 その中で、ファイルを開き、拡張子のコンプライアンス、ファイルの存在などを確認します。



 ReaderWriterPCX::ReaderWriterPCX() { supportsExtension("pcx","PCX Image format"); } const char* ReaderWriterPCX::className() const { return "PCX Image Reader"; }
      
      





主な機能



関数の戻り値のタイプはosgDB :: ReaderWriter :: ReadResultですが、この場合、osg :: Imageが返されます。 まず、画像の寸法やピクセルデータ自体など、いくつかの画像パラメーターを知る必要があります。 アルファチャネルはこの形式を使用せず、256以上のパレットのみをサポートします。 この形式は、 スーパーデュパー RLEデータ圧縮を使用します。 ウィキからの引用:

このような圧縮のアルゴリズムは非常に高速であり、メモリを少し消費しますが、写真やより詳細なコンピューターグラフィックスの圧縮にはあまり効率的ではなく、実用的ではありません。



ロスレス圧縮が使用されます。 画像を保存するとき、同じ色の連続するピクセルが結合され、各ピクセルの色を指定する代わりに、ピクセルのグループの色とその数が示されます。 このようなアルゴリズムは、同じ色の領域が存在する画像を圧縮します。


そのため、ファイルを開いてその署名を読み取ります。 正しい場合は先に進みます。 残りのデータをチェックし、サイズ、パレットを読み取ります(256色のファイルの最後にあります)。



 fin.read((char*) &pcx->Identifier, sizeof(pcx->Identifier)); if (pcx->Identifier != 0x0a) { OSG_WARN << "Invalid PCX Identifier\n"; return 0; }
      
      





展開アルゴリズム自体:



 for (int h = height_ret - 1; h >= 0; --h) { for (int w = 0; w < width_ret; ++w) { if(!count) { if(!fin.read((char*) &tmp, sizeof(tmp))) { OSG_WARN << "file truncated\n"; return 0; } if( (tmp & 0xc0) == 0xc0) { count = tmp & 0x3f; if(!fin.read((char*) &tmp, sizeof(tmp))) { OSG_WARN << "file truncated\n"; return 0; } } else { count = 1; } } index = h * width_ret + w; imageBuffer[index].red = colorPalette[tmp].red; imageBuffer[index].green = colorPalette[tmp].green; imageBuffer[index].blue = colorPalette[tmp].blue; --count; } }
      
      





imageBuffer配列はデータです。 ピクセル数の3色で構成されています。 つまり、これは解凍されたデータです。 これらは画像データのインストール時に使用され、形式とサイズはそれぞれGL_RGBと3バイトが選択されます。



プラグインをpluginsフォルダーにコピーする必要があります。 これは/usr/lib/osgPlugins-3.2.0/です(Linuxを使用しています)。 例で示されているosgmovieで開くことで確認できます。 ファイルの最後に、プラグインを接続するコードを示す必要があります。



 REGISTER_OSGPLUGIN(pcx, ReaderWriterPCX)
      
      





エピローグ



プラグインの存在により、OpenSceneGraphを使用して古いゲーム用のエンジンを新しいグラフィックで記述したり、ゲームにデータを保存するために独自の形式を使用したりすることができます。 次回の記事では、3D形式を読み取るためのプラグインを作成する予定です。



ソース: bitbucket.org/darkprof/pcx/src



All Articles