トップページ > 記事閲覧
CPU専用のsoftimageの画像処理を1ピクセル単位で行いたいのですが
名前:littlestream 日時: 2022/02/11 16:19

こんにちは。littlestreamという者です。 自前の3DCGのクラスライブラリをDXLIBで作りたい (?DXLIBを使う時点で既に自前ではないのですが) のでまずはポリゴンを描く命令を作った事は作ったのですが、 DrawPixelで実装したらFPSが30くらいに落ちてしまいました。 なので、ソフトイメージを使ってCPU専用の点が打てる 処理が作れないか試していました。 しかし、以下のソースを書いたら、 CPU専用の命令というかソフトイメージが最初に数フレームで消えてしまうのと FPSが0から2の処理速度の遅さで困っています。(今さっきもそうでした) ただ、サンプルプログラムや皆さんの投稿を見ると 皆さんが普通に使えるはずみたいでサンプルプログラムは 普通に動くのはとても良いことにも 思えるのですが、自分がサブクラス化したときに何故か 自分はうまく思った通りに点や線、ポリゴンが描画されずに 動かないのが続いたので気になって質問しました。 class Graph{ private: int CPUIMAGE[MAXIMAGE]; int Right[480]; int Left[480]; public: void JisakuLine(int x1,int y1,int x2,int y2,int Col,int SW=0) { for(int i=0;i<512;i++) { int x=(x1*(512-i)+x2*i)/512; int y=(y1*(512-i)+y2*i)/512; if(Right[y]<x) Right[y]=x; if(Left[y]>x) Left[y]=x; DrawCPUImage(0,x,y,255,0,0,128); } } void MakeCPUImage(int i,int W,int H) { // 空のフルカラー画像を作成する CPUIMAGE[i]=MakeARGB8ColorSoftImage(W,H) ; } void DrawCPUImage(int HandleNum,int x,int y,int R,int G,int B,int alpha) { int i,j; DrawBox(0,0,600,320,GetColor(255,255,255),TRUE); // 縦方向に透明グラデーションした真っ赤な画像を作成する //for( i = 0; i < 256; i ++ ) { //for( j = 0; j < 256; j ++ ) { // 色をセット DrawPixelSoftImage( CPUIMAGE[HandleNum],x,y,R,G,B,alpha) ; } } // 透明かどうかわかるように画面を緑で塗りつぶす DrawBox( 0, 0, 640, 480, GetColor( 0, 255, 0 ), TRUE ) ; } void FlipScreen() { // グラフィックハンドルを作成 grhandle = CreateGraphFromSoftImage(CPUIMAGE[0]) ; // 使い終わったら解放 //DeleteSoftImage(CPUIMAGE[HandleNum]); InitSoftImage(); // グラフィックハンドルを描画 DrawGraph( 0, 0, grhandle, TRUE ) ; // グラフィックハンドルの削除 DeleteGraph( grhandle ) ; } }; //うえのクラスの呼び出し元はこうなっています。 //WinMainのゲームの中のメインループ内では G.MakeCPUImage(0,640,480); // ループ while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { // 画面を初期化する ClearDrawScreen() ; ////G.Clear(); // キー入力取得 Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 ) ; int X[3],Y[3]; int X2[3],Y2[3]; X[0]=300;Y[0]=30; X[1]=80;Y[1]=430; X[2]=620;Y[2]=80; G.JisakuGouraudPolygon(0,X2,Y2,255,0,0,0,255,0,0,0,255); G.FlipScreen(); PrevJoy1=(Key & PAD_INPUT_1); G.CalcFPS(); ScreenFlip() ; } DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 }
メンテ

Page: 1 |

Re: CPU専用のsoftimageの画像処理を1ピクセル単位で行いたいのですが ( No.1 )
名前:littlestream 日時:2022/02/11 16:21

失礼しました。 どうすれば処理遅延と図形が 描けるかが知りたいのですが教えてください。 よろしくお願いします。
メンテ
Re: CPU専用のsoftimageの画像処理を1ピクセル単位で行いたいのですが ( No.2 )
名前:管理人 日時:2022/02/12 14:24

softimageを使用する場合も DrawPixelSoftImage を使用するとあまり速度が出ませんので、 高速に処理したい場合は GetImageAddressSoftImage で softimage の画像データが格納されている メモリアドレスを取得して、画像データをポインタで直接変更する必要があります softimage の画像内で 256x256サイズのグラデーション色の矩形が左右に移動する、 というプログラムを組んでみましたので、よろしければ参考にしてください m(_ _)m #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int Screen ; int x = 0 ; int xadd = 8 ; int y = 240 - 128 ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // 640x480 のサイズのソフトイメージを作成 Screen = MakeARGB8ColorSoftImage( 640, 480 ) ; // 描画先を裏画面に変更 SetDrawScreen( DX_SCREEN_BACK ) ; // メインループ while( ProcessMessage() == 0 ) { // 画面をクリア ClearDrawScreen() ; // ソフトイメージをクリア( R=0 G=0 B=0 A=0 で塗りつぶし ) FillSoftImage( Screen, 0, 0, 0, 0 ) ; // 256x256 の矩形の座標を画面内を左右に移動させる処理 if( ( xadd > 0 && x == 640 - 256 ) || ( xadd < 0 && x == 0 ) ) { xadd = -xadd ; } x += xadd ; // ソフトイメージの1ライン辺りのバイト数を取得 // ( 1ピクセル 4バイトなので、1ピクセル単位にするために 4で割る ) int Pitch = GetPitchSoftImage( Screen ) / 4 ; // ソフトイメージが格納されているメモリアドレスを取得 unsigned int *Image = ( unsigned int * )GetImageAddressSoftImage( Screen ) ; // 矩形の描画先にメモリアドレスを変更 Image += x + Pitch * y ; // グラデーション付きの 256x256 サイズの矩形を描画 for( int i = 0 ; i < 256 ; i ++ ) { for( int j = 0 ; j < 256 ; j ++ ) { // ソフトイメージが格納されているメモリ領域に直接色の値を代入 // ARGB8 形式は 0xAARRGGBB なので、0xffff でアルファ値と赤成分が 255 // j << 8 で緑成分が j、i はそのまま青成分 Image[ j ] = ( 0xffff0000 ) | ( j << 8 ) | i ; } // 1ライン分描画したらメモリアドレスを次のラインの先頭に移動 Image += Pitch ; } // ソフトイメージを画面に描画 DrawSoftImage( 0, 0, Screen ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; }
メンテ
Re: CPU専用のsoftimageの画像処理を1ピクセル単位で行いたいのですが ( No.3 )
名前:littlestream 日時:2022/02/12 16:55

管理人さんへ 早速の返信ありがとうございます。 自分なりに書いてみたクラスは以下のようになりました。 全てうまく行きましたのでとてもうれしいです。ありがとうございました。 class Graph{ private: int FPS; int Left[480];//for FlatShading int Right[480]; int GLeft[480];//for Gouraud Shading int GRight[480]; int LeftR[480]; int ...RightLeftRandGandB//ここは自明だと思われるので int Screen; int grhandle; int WIDTH,HEIGHT; int *Image; public: void JisakuGouraudPolygon(int handle,int x[3],int y[3],int R1,int G1,int B1,int R2,int G2,int B2, int R3,int G3,int B3) { int y2; for(y2=0;y2<480;y2++) { GLeft[y2]=640; GRight[y2]=0; LeftR[y2]=0; LeftG[y2]=0; LeftB[y2]=0; RightR[y2]=0; RightG[y2]=0; RightB[y2]=0; } JisakuGLine(x[0],y[0],x[1],y[1],R1,G1,B1,R2,G2,B2); JisakuGLine(x[1],y[1],x[2],y[2],R2,G2,B2,R3,G3,B3); JisakuGLine(x[2],y[2],x[0],y[0],R3,G3,B3,R1,G1,B1); for(y2=0;y2<480;y2++) { if(GLeft[y2]==640 || GRight[y2]==0) continue; JisakuGLine(GLeft[y2],y2,GRight[y2],y2+1,LeftR[y2],LeftG[y2],LeftB[y2],RightR[y2],RightG[y2],RightB[y2]); } } void JisakuPolygon(int x[3],int y[3],int col) { for(int y2=0;y2<480;y2++) { Left[y2]=65816; Right[y2]=-65816; } JisakuLine(x[0],y[0],x[1],y[1],col); JisakuLine(x[1],y[1],x[2],y[2],col); JisakuLine(x[2],y[2],x[0],y[0],col); for(int y2=0;y2<480;y2++) { if(Left[y2]==65816 || Right[y2]==-65816) continue; JisakuLine(Left[y2],y2,Right[y2],y2,col); } } void JisakuGLine(int x1,int y1,int x2,int y2,int R1,int G1,int B1,int R2,int G2,int B2,int SW=0) { for(int i=0;i<512;i++) { int x=(x1*(512-i)+x2*i)/512; int y=(y1*(512-i)+y2*i)/512; int R=(R1*(512-i)+R2*i)/512; int G=(G1*(512-i)+G2*i)/512; int B=(B1*(512-i)+B2*i)/512; if(GRight[y]<x) { GRight[y]=x; RightR[y]=R; RightG[y]=G; RightB[y]=B; } if(GLeft[y]>x) { GLeft[y]=x; LeftR[y]=R; LeftG[y]=G; LeftB[y]=B; } //PSET(x,y,RGB(R,G,B)); DrawCPUImage(x,y,R,G,B,255); } } void JisakuLine(int x1,int y1,int x2,int y2,int Col,int SW=0) { for(int i=0;i<512;i++) { int x=(x1*(512-i)+x2*i)/512; int y=(y1*(512-i)+y2*i)/512; if(Right[y]<x) Right[y]=x; if(Left[y]>x) Left[y]=x; //PSET(x,y,Col); DrawCPUImage(x,y,255,0,0,255); } } void Clear() { // ソフトイメージをクリア( R=0 G=0 B=0 A=0 で塗りつぶし ) FillSoftImage( Screen, 0, 0, 0, 0 ) ; } void MakeCPUImage(int W,int H) { // 640x480 のサイズのソフトイメージを作成 Screen = MakeARGB8ColorSoftImage( 640, 480 ) ; } void DrawCPUImage(int x,int y,int R,int G,int B,int alpha) { // ソフトイメージの1ライン辺りのバイト数を取得 // ( 1ピクセル 4バイトなので、1ピクセル単位にするために 4で割る ) int Pitch = GetPitchSoftImage( Screen ) / 4 ; // ソフトイメージが格納されているメモリアドレスを取得 Image = (int*)GetImageAddressSoftImage( Screen ) ; // 矩形の描画先にメモリアドレスを変更 Image[x + Pitch * y]=GetColor(R,G,B); } void FlipScreen() { // ソフトイメージを画面に描画 DrawSoftImage( 0, 0, Screen ) ; } void CalcFPS() { static int Before=0; static int tmp=0; if(GetTickCount()-Before>1000) { Before=GetTickCount(); tmp=FPS; FPS=0; }else{ FPS++; } DrawFormatString(0,0,GetColor(255,0,0),"FPS ON = %d",tmp); } };
メンテ
Re: CPU専用のsoftimageの画像処理を1ピクセル単位で行いたいのですが ( No.4 )
名前:littlestream(解決) 日時:2022/02/12 16:58

解決しました。ありがとうございました。 またの機会がありましたらよろしくお願いします。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存