BitBltによるビットマップ編集の仕方

[戻る]
麗音 [E-Mail] 2002/06/14(金) 09:03:27
現在、3Dアニメーションソフトを開発しているのですが、その中で、BitBltを使おうとして
いるのですがうまくいきません。
OpenGLでテクスチャマップするため、メモリ上で、ビットマップをスライドさせたいのですが
どのようにすればよろしいでしょうか?

いろんなサイトを調べてみたのですが、それぞれいろんな変数(CBitmapや
BITMAPINFO構造体など)を使用していて、どの変数を用いるのが便利なのか
分かりません。また、ビットパターンについても理解不足です。
できればBitmapに関して、詳しく教えていただきたいのですが・・・。
詳しい方がおられましたら、教えてください。
よろしくお願いします。

PAI 2002/06/14(金) 10:40:13
どううまくいかないのかがわかりません。
方針からわからない、ということですか?
現状はどのようになっているのでしょうか?

くたくた 2002/06/14(金) 11:13:40
>OpenGLでテクスチャマップするため、メモリ上で、ビットマップをスライドさせたい
「テクスチャ切り替えでのアニメーションをするポリゴンを描画したい」という解釈で説明しま
す。又、「テクスチャ付きポリゴンを描画する方法は既知」という前提も含めます。

短く言うと、
o 初期化時にglBindTexture()とglTexImage2D()で全アニメーションパターンを
  OpenGLテクスチャメモリへ転送。
o 描画時にglBindTexture()で適用対象テクスチャを選択
という感じです。

>BitBltを使おうとしているのですがうまくいきません。
同一のテクスチャ領域へ 違うテクスチャ画像を 次々と転送し、
アニメーションさせようしているという解釈で説明します。

やり方は 上記説明と殆ど 変わりありません。
違いは
o "システムメモリ上"に全アニメーションパターンを展開
o 実行速度。(後者の方法が遅くなるのは自明)
という程度です。無論ですが、Win32APIのBitBlt系は使えません。

>また、ビットパターンについても理解不足です。
"ピクセルフォーマット"で調べてみて下さい。

これまでの説明は OpenGL Release1.2(3年くらい前)の頃での事です。
今ではもっといい方法があるかもしれません。又、本格的にOpenGLをやるなら
"赤本(ISBN4-7952-9645-6 \11000)"を参照するのがベストです。

麗音 [E-Mail] 2002/06/14(金) 12:16:27
返信、ありがとうございます。

現在、作成しているのは、テクスチャを物体に貼り付けることができるのですが、
その張り付け位置や張り付け範囲などを変えられるようにしたいのです。
ディスプレイリストを作り直さずに描画するために、描画する時にテクスチャのビットマップを
編集して表示させたいのです。

つまり、glTexCoord2d(U,V);のUとVを変更することなく画像を編集することで
表示させたいと考えています。
そのためにBitBltやStretchBltなどをしようと思ったのですが、DCやビットマップに関する
知識が浅いので、何から進めればいいのか途方にくれています。
具体的に現在テストしているプログラムはどのように進めるべきでしょうか?

//問題
1、ビットマップファイルを読み込む
2、メモリ上に読み込んだビットマップの2倍の大きさのビットマップを作成し、
黒で塗りつぶす。
3、2のビットマップの右下隅に1のビットマップを張り付け。
4、3のビットマップをウインドウに表示

このようなプログラムを作りたいのですが、どのようにすればよろしいでしょうか?
手順や概念だけでも教えていただけないでしょうか?

dairygoods 2002/06/14(金) 13:58:42
> 1、ビットマップファイルを読み込む
ファイルがリソースにあるなら:
CBitmap::LoadBitmap()
他所にある場合:
http://www.grace.ne.jp/~gok/assem/wincode/graphic/0001.htm


ここからはメモリデバイスコンテキストを使います。
CDC::CreateCompatibleDC()

> 2、メモリ上に読み込んだビットマップの2倍の大きさのビットマップを作成し、
CBitmap::CreateCompatibleBitmap()

> 黒で塗りつぶす。
CDC::SelectObject(CBitmap*)
CDC::FillRect()など。

> 3、2のビットマップの右下隅に1のビットマップを張り付け。
CDC::DrawState()あたりかな。

> 4、3のビットマップをウインドウに表示
CDC::BitBlt()で画面デバイスコンテキストに転送。

くたくた 2002/06/14(金) 17:26:21
失礼致しました。Winの質問なのですね。
dairygoodsさんの説明どおりでいけると思います。

但し、4番だけはOpenGLのレンダリングになる為、補足します。
システムメモリに描画した最終結果の画像のメモリイメージは
はGetDIBits()やGetGetBitmapBits()で取得出来ます。
後はOpenGLが要求するピクセルフォーマットに変換、転送で完了です。

麗音 [E-Mail] 2002/06/18(火) 15:53:38
返信、ありがとうございます。

いろいろ試行錯誤してやってみたんですが、以下のような現象が起きてしまいました。
お気付きの点がありましたら、教えてください。

1、メモリDCを2つ作成し、一方に読み込んだBMP、他方に新しいBMPを選択する。
  読み込んだBMPを縮小し、新しいBMPにBitBltする。
  新しいBMPのメモリイメージを取得。
  gluBuild2DMipmapsを使用し、OpenGLで描画。
  以上のようにしたところ、画像の色がおかしくなる。

2、ディスプレイデバイスとCompatibleなメモリDCを作成。
  メモリDCに読み込んだBMP、ディスプレイデバイスに新しいBMPを選択する。
  以下の処理は1と同様。
  そうしたところ、画面に大きなイメージが表示されOpenGLの描画はできていない。

くたくた 2002/06/18(火) 18:25:42
>1、画像の色がおかしくなる。
  原因の特定方法は簡単です。各段で画像の正当性を検査すればいいです。
  無論、2分探索で検査コード挿入位置を決めて下さい。各段とは、
  o BMPを読み込んだ時
  o 上記を縮小時
  o BitBlt後の転送先画像
  です。検査は「GDIで描画した結果を確認する方法」が手っ取り早いと思います。
  上記全てに問題がない場合は gluBuild2DMipmaps()のに渡す画像のピクセルフォーマット
  がおかしい事になります。おそらく色成分の格納位置がずれているのではないでしょうか

>2、画面に大きなイメージが表示されOpenGLの描画はできていない。
  当然の結果です。デスクトップDCに縮小後の画像を描画したのですから。
  従って、この方法は問題解決になりません。

これまでに紹介した操作は、DC周辺の知識がある事を前提にしています。
1の方法を採るのであれば、まずこれらを理解して下さい。
採用しないのであれば、全てを自前で行ってみて下さい。
後者の方が早く結論に辿り着く事もありますよ。がんばって下さい。では。

麗音 2002/06/20(木) 14:57:24
[[解決]]
返信ありがとうございます。

問題解決しました。
モニタの表示色が65536色になっていたため
ビットパターンが取得できていないのが原因でした。
お手数おかけしました。
モニタの表示色を上げると直りました。

また質問することがあるかと思いますが、
よろしくお願いします。

古いスレッドには追加発言できません。