C言語初心者です。
以前、ここの掲示板で質問をして、おかげさまで読み込んだRawデータをDirectXで表示することが出来ました。
下記のコードはその改良版で、NoiseTest0000.raw-NoiseTest5954.rawというRGB 8bitX3の連番カラー静止画を読み込んで、Vsyncに同期して表示するプログラムです。
SSD上に、静止画ファイルを置いておけば、データ読み込みは3msec程度で済むので、連番静止画を動画の様に見せることが出来てます。
(1)行いたいこと。下記のDrawPixelSoftImageで描画データをhandleに書き込んでいますが、この部分を高速化したいと思ってます。
別にDrawPixelSoftImageを使わなくても良いので、他に好適な別関数があれば教えて頂けませんでしょうか。
// Image Write
DrawPixelSoftImage( handle0, x, y + y_offset , in[y*inwidth*3 + x*3], in[y*inwidth*3 + x*3+1], in[y*inwidth*3 + x*3 +2], 255 ) ;
(2)高速化したい理由
今は720X480 8x3chの画像ですが、もっと大きな画像を描画しようとしたとき、このhandle0へのデータ書き込みだけで、OpenMPで並列化しても、22msec程度かかかります。
30FPS位(33msec)で表示したいので、この部分だけで22msecかかると、CPUで何か画像処理をさせる時間が短くなり、たいした処理が出来なくなります。
(3)その他の要望
今は8bitX3CHのカラー画像ですが、8bitx1CHのグレースケール画像を表示させることも考えています。
DrawPixelSoftImageだとグレースケールの場合、RGBに同一データを書き込むことになりますが、これだとグレースケール8bitX1CHなのに、3CH分を書き込まねばならず書き込み時間を損することになります。
グレースケール画像を効率的にhandleに渡す方法は有りませんでしょうか?
どなたか、良い方法をご存知でしたら、ご教授頂ければ幸いです。
#include "DxLib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <omp.h>
int WindowWidth = 1680;
int WindowHeight = 1050;
int LOOP;
int START = 0;
int END = 5954;
int inwidth = 720;
int inheight = 480;
int y_offset = 50;
int Color;
int outwidth = 0;
int outheight =0;
int x,y,i,j,cno,xx=0;
int StartTime0,EndTime0,EndTime1,EndTime2;
//画像入出力イメージ
char *in;
int thread_num = 4;
char ch1[512],ch2[512] ;
char c_zero[5] = "0000";
char no[10];
FILE *fp1;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int handle0, grhandle0 ;
//LCD表示初期設定
SetScreenMemToVramFlag( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1;
//描画Windowsのサイズ設定
SetGraphMode( WindowWidth , WindowHeight , 32 ) ;
ChangeWindowMode(TRUE); // ウィンドウモードに設定
SetDrawScreen( DX_SCREEN_BACK ); //描画先を表画面に設定
in =(char* )malloc(inwidth*inheight*3);
for(LOOP = START;LOOP <= END;LOOP++){
//入力画像データFILE名作成
//Input_image Read from FILE
sprintf(no,"%d",LOOP);
cno = (int)(strlen(no));
strcpy(ch1,"");
strcpy(ch1,"NoiseTest");
strncat(ch1,c_zero,4 -cno);
strcat(ch1,no);
strcat(ch1,".raw");
printf("INPUT FILE NAME:%s\n",ch1);
//Buffer確保
//Input_image Read from FILE
StartTime0 = GetNowCount() ;
fp1 = fopen(ch1,"rb");
if(fp1 == NULL){
printf("Input FILE Error!!\n");
getchar();
return -1;
}
fread(in,sizeof(char),inwidth*inheight*3,fp1);
fclose(fp1);
EndTime0 = GetNowCount() ;
//*************
//初期画面表示
//*************
ClearDrawScreen();//ScreenのClear
// 白色の値を取得
Color = GetColor( 255 , 255 , 255 ) ;
EndTime1 = GetNowCount() ;
// 空のフルカラー画像を作成する
handle0 = MakeARGB8ColorSoftImage(inwidth+50,inheight+50) ;
//Thread数の設定
omp_set_num_threads(4);
#pragma omp parallel for private(x), firstprivate(y_offset,inwidth)
/* 入力データを画面表示メモリにSetする。*/
for( y = 0; y < inheight; y ++ )
{
for( x = 0; x < inwidth; x ++ )
{
// Image Write
DrawPixelSoftImage( handle0, x, y + y_offset , in[y*inwidth*3 + x*3], in[y*inwidth*3 + x*3+1], in[y*inwidth*3 + x*3 +2], 255 ) ;
}
}
// グラフィックハンドルを作成
grhandle0 = CreateGraphFromSoftImage( handle0 ) ;
// 使い終わったら解放
DeleteSoftImage( handle0 ) ;
// グラフィックハンドルを描画
DrawGraph( 0, 0, grhandle0, TRUE ) ;
EndTime2 = GetNowCount() ;
Color = GetColor( 255 , 255 , 255 ) ;
DrawFormatString( 20, 650, Color, "Read Input Image Time:%d[msec]\n",EndTime0-StartTime0 ) ;
DrawFormatString( 20, 680, Color,"DirectX Process Time:%d[msec]\n",EndTime2-EndTime1 ) ;
//LCD Vsync 2Wait(30FPS)
WaitVSync( 2 ) ;
ScreenFlip(); //裏画面を表画面に反映
//メモリ読み込んだ画像を消去する。
//これを入れないと、多数の静止画を読み込んだ時、メモリが更新されなくなる。
InitGraph() ;
}
//Memory Release
free(in);
// キー入力待ち
WaitKey();
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}