Re: 戦車や船などの走った跡 ( No.1 ) |
- 名前:さかな 日時:2009/02/05 17:02
MakeGraph等で作ったハンドルにどんどん上書きしていけばいいのではないでしょうか?
|
× ( No.2 ) |
- 名前:M 日時:2009/02/07 06:25
<編集しました。>
似たスレッドかあり目的の関数が見つかりました。
しかし失敗しました。
=以下コピペ=
int SubScreen;
SetDrawValidGraphCreateFlag( TRUE );
SubScreen = MakeGraph( 640, 480 );
SetDrawValidGraphCreateFlag( FALSE );
こうして作成した画像ハンドルは SetDrawScreen で描画先とすることが出来ます。
SetDrawScreen( SubScreen );
//コピペここまで
ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=past&no=387
より、管理人様の返信のコピー&ペーストです。
解決はしていません。(↓のスレッドに続きます。)
|
解決していませんでしたorz ( No.3 ) |
- 名前:M 日時:2009/02/07 06:52
以下のコードとまったく同じ効果を違う方法で得たいのですが、上手く行きません。
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
int SubScreen;
SetDrawValidGraphCreateFlag( TRUE );
SubScreen = MakeGraph(800,640);
SetDrawValidGraphCreateFlag( FALSE );
while(ProcessMessage()==0){
SetDrawScreen( SubScreen );
DrawString(0,0,"dsa",GetColor(0,0,255));
SetDrawScreen(DX_SCREEN_BACK );
DrawGraph(0,0,SubScreen,true);
ScreenFlip();
}
DxLib_End();
return 0;
}
//↑このコードでは、期待通りの働きをしてくれます。(後述で例外を指摘します。)
何より一番の問題は・・・
ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=past&no=387
より、管理人様の返信にある、
「ただ、この機能は他の機能に比べて正常に動作するグラフィックチップの
敷居が高いので、余りお勧めできません。」
ということです。
これが、もし1%や2%などのPCにしか当てはまらないのならば、余り気にしないのですが…
実際のところ、どの程度のPCは正常に動作できないのかが分からないので、他の方法を探している次第です。
どのグラフィックカード(チップ?)でも大抵は正常に表示できるようにしたいのです。
この正常に動かない可能性を踏まえて、それを妥協した場合ですが、
上記のコードの MakeGraph(int,int) で、少なくとも私の環境ではなぜか
intの値を5000などと大きくすると、上記の描画時にウィンドウではなく、
スクリーン全体の左上を0,0として描画されてしまいます。
例えば、ゲームしかウィンドウを開いていなかった場合、ゲームをウィンドウモードで表示しているにも関わらず、デスクトップ左上に描画されているような感じです。
また、MakeGraph の代わりに LoadGraphも試みましたが、画像が800×5120と大きいためか、
これも上記と同じ症状です。
・「なぜそんなに大きくしたいのか?」
私は背景が縦にスクロールされるタイプのゲームを作成していて、
戦車などのオブジェクトは背景を無視してウィンドウ左上を0,0として座標を保存しているため、
戦車の跡などは、背景画像に直接、書き込むのが一番楽だと思ったのですが、
どうもその背景が大きすぎるためか、上記の方法では上手くいきませんでした。
ちなみに画像は、(800,5120) のjpg 150kb です。
(背景が動いた同じ量だけ、戦車も動かして地上に戦車があるように表示しています。)
どうにか、どのグラフィックチップでも大抵問題なく、同じような効果を得られないでしょうか?
|
Re: 戦車や船などの走った跡 ( No.4 ) |
- 名前:管理人 日時:2009/02/09 19:38
> 以下のコードとまったく同じ効果を違う方法で得たいのですが、上手く行きません。
具体的にはどのように上手く行かないのでしょうか?
> どのグラフィックカード(チップ?)でも大抵は正常に表示できるようにしたいのです。
それがご希望でしたら、MakeGraph で作成した画像に描画する機能を使用するべきではないと思います
> intの値を5000などと大きくすると、上記の描画時にウィンドウではなく、
> スクリーン全体の左上を0,0として描画されてしまいます。
スクリーン全体の左上を0,0として描画されてしまうのはDXライブラリのバグである可能性が
高いですが、何が原因であるにしても 4096 を超えるサイズのテクスチャはここ数年で登場した
グラフィックチップでようやく対応が始まったというところなので、殆どの環境で正常に
動作させたいとお考えでしたら尚のこと描画可能画像は使用すべきではないと思います
> どうもその背景が大きすぎるためか、上記の方法では上手くいきませんでした。
> ちなみに画像は、(800,5120) のjpg 150kb です。
本件とは直接関係ありませんが、DirectX は jpeg画像を jpeg画像のまま扱う機能は備わっていませんので、
LoadGraph で読み込まれた画像が無圧縮BMPや無圧縮Tga等以外の場合はまず無圧縮の BMP 形式(に近いもの)に
変換されます。すると、800x5120 サイズの画像は、読み込み後には
800×5120×4バイト=16384000バイト (16bitカラーの場合は半分の8192000バイト)
16384000バイト=15.625メガバイト
と、16MB弱のサイズになります
グラフィックチップに拘りのないノートPC等ではこの時点で正常に動作しない可能性がありますので、
多くの環境で正常に動作させることをお考えの場合は2DRPGのマップ表示のように、32×32サイズの
チップセットを並べてマップを表現する方法を採用された方が良いと思います
> どうにか、どのグラフィックチップでも大抵問題なく、同じような効果を得られないでしょうか?
まず跡の表現方法としては最初にMさんが採られていた一つ一つDrawGraph 等の関数で描画する方法で
良いと思います( 一番正常に動作する環境が多くなると思いますので )
そして、700個という数ですが、CPU負荷が原因で700個描画すると処理落ちが発生するということでしたら
最適化有りのリリースビルドをすることでそれなりに処理が高速化されますのでもしかしたら元のままの処理で
700個を処理落ちなく処理することができるかもしれません
もしそうではなくグラフィックチップの性能がネックになって処理落ちが発生しているとしますと、
残念ながら700個という数をあきらめるしかありません
また、Mさんの環境で700個描画しても処理落ちしないようになっても、Mさんが「これくらいの環境だったら
処理落ちなく動いてほしい」という環境で処理落ちせずに動作しなければ意味が無いので、その点も考慮する
必要があります
最後に高速に描画処理を行うポイントです
1.同じ画像は可能な限り連続して描画するとテクスチャ変更と頂点フラッシュが発生しないので描画処理が高速になります
2.扱う画像は 2 のn乗のサイズ( 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 )にすると
テクスチャ分割が行われる可能性が無いので高速な描画が期待できます
3.DerivationGraph で派生させたグラフィックハンドル達はすべて派生元のグラフィックハンドルの
テクスチャを使用するので、同じ画像から DerivationGraph させたグラフィックハンドルは、
グラフィックハンドルが違っても1と同じ高速描画効果が得られます
( ただし、DerivationGraph をする元の画像が 2 のn乗サイズである必要があります )
なので、開発効率に支障が出ない範囲で、色々な画像を 2のn乗サイズの画像に敷き詰めて、
DerivationGraph で派生させて使用すると、高速に描画することができます
4.LoadDivGraph はDXライブラリの中で分割元画像を LoadGraph して、DerivationGraph で
派生させているので、LoadDivGraph で分割読み込みしたグラフィックハンドル達も、1と同じ
高速描画効果が得られます( ただし、LoadDivGraph で読み込む分割元画像が 2 のn乗サイズである
必要があります )
5.描画関数の処理負荷は DrawGraph < DrawExtendGraph < DrawRotaGraph < DrawModiGraph ≒ DrawRectGraph です
( ただ、同じテクスチャを使用した描画を連続させることで得られる高速化効果よりも処理負荷への影響は少ないです )
|
Re: 戦車や船などの走った跡 ( No.5 ) |
- 名前:M 日時:2009/02/10 09:00
細かい解説ありがとうございます。<(_ _)>
>具体的にはどのように上手く行かないのでしょうか?
というのは、ただたんに思いつかないというだけです。
ややこしい言い方をしてしまって、すみません。
面倒くさがってタイル(チップ)を避けてました><
背景は、チップで表示するようにします。
>最適化有りのリリースビルドをする
そういえば、そのことを忘れていました。
>LoadGraph で読み込まれた画像が無圧縮BMPや
>無圧縮Tga等以外の場合はまず無圧縮の BMP 形式(に近いもの)に変換されます。
なんと!!
それは壮大なメモリ(?)の無駄遣いではないですかw
跡のほうは、MakeGraphはあきらめて、たくさん描画する方針にしてみます。
>最後に高速に描画処理を行うポイントです
ありがとうございます!!
めっさ助かります。
すぐには解決の報告はできないかもしれませんが、教えていただいた事を参考にして直してきます。
(*追加)
ひとつだけ質問があります。
>同じ画像は可能な限り連続して描画するとテクスチャ変更と頂点フラッシュが発生しないので描画処理が高速になります
ということですが、すると、チップで表示する際も左上から右下と描画する方法
for(int x = 0; x < (xのMAX値);x++)
for(int y = 0; y < (yのMAX値); y++)
DrawGraph(x*32,y*32,ChipGraph[ GraphicChipAt[x][y] ],false);
//ChipGraph[int]は、指定されたチップの種類の画像ハンドルを返す。
//GraphicChipAt[int][int] は、指定された座標のチップの種類を返す。
とやるよりも、チップをベースでループする方法
for(int chipNum = 0; chipNum < (chipNumの種類数);chipNum++){
for(int x = 0; x < (xのMAX値);x++)
for(int y = 0; y < (yのMAX値); y++){
if(graphicChipAt[x][y] == chipNum)
DrawGraph(x*32,y*32,ChipGraph[chipNum],false);
}
}
の方が高速ということでしょうか?
ループの量は、かなり増えてますが・・・。
|
Re: 戦車や船などの走った跡 ( No.6 ) |
- 名前:憂煉 日時:2009/02/10 15:23
はじめましてMさん。
追加質問に関してですが、描画前に描画順序の並び替えをするのはどうでしょうか?
struct POSLIST
{
int x,y;
POSLIST *next;
POSLIST():x(0),y(0),next(NULL){}
};
POSLIST posdata[x_max * y_max]; //描画する分だけ準備
POSLIST *poslist[chipNum]; //チップの種類だけ準備
void draw()
{
int i = 0;
POSLIST *tmp;
for(i = 0;i < chip_max;++i)poslist[i] = NULL;
for(int x = 0;x < x_max;++x)
for(int y = 0;y < y_max;++y)
{
//チップの種類別リストを生成するループ
posdata[i].next = poslist[graphicChipAt[x][y]];
posdata[i].x = x * 32;
posdata[i].y = y * 32;
poslist[graphicChipAt[x][y]] = posdata + i;
++i;
}
for(i = 0;i < chip_max;++i)
for(tmp = poslist + i;tmp != NULL;tmp = tmp->next)
{
//リストに従って描画するループ
DrawGraph(tmp->x,tmp->y,i,false);
}
}
一気に書いたのでバグがあるかも知れませんがご参考程度にどうぞ
|
Re: 戦車や船などの走った跡 ( No.7 ) |
- 名前:管理人 日時:2009/02/10 19:36
> ひとつだけ質問があります。
チップ画像が全て個別の画像ファイルになっていて、それを一つ一つ LoadGraph で読み込んで
ChipGraph 配列にグラフィックハンドルを代入したのだとしたらMさんが書き込まれた後者の
プログラムのようにチップ別に描画したほうが描画処理としては高速ですが、2のn乗サイズの
画像にチップを並べて、それを LoadDivGraph で読み込んだ場合は ChipGraph に格納される
グラフィックハンドルの値は全て別ですが使用しているテクスチャは同じものとなりますので、
前者のプログラムでも「同じ画像を連続して描画している」ことと同じになり、高速に描画することができます。
|
Re: 戦車や船などの走った跡 ( No.8 ) |
- 名前:M 日時:2009/02/11 05:20
なるほど!
ありがとうございます<(_ _)>
ご協力のおかげで、かなり進歩しました。
戦車の足跡の方ですが、代替案を思いつきました。
やはり、細かくたくさん描画するのは数がどうしてもすごいことになり処理落ちがありうるため、避ける事にしました。
その代わりに、やや残念ですが、移動ルートをチップに合わせて固定します。
そこで、新たなチップレイヤー(第二レイヤー)を背景の上に作成し、
戦車が通ったルートと同じチップ上の第二レイヤーに足跡を描画することで、解決しそうです。
チップベースに描画をする事で、意外と本来の問題を解決することができました。
ありがとうございました。<(_ _)>
|
|