|
Name: ボンバー ..ぴよぴよ(490ポイント)
Date: 2010/09/15(水) 22:27
No:61808
|
|
Title: DXライブラリが実行されない・・・
|
|
DXライブラリでmoriというbmp式の画像を分割して読み込み、表示させるプログラムを作成しました。
しかし。
コンパイル→ソリューションのビルド→デバッグなしで実行
・・・してもなにも起きませんorz
なぜでしょうか!?
☆まとめ
@DXライブラリを使用するためのプロジェクトの設定はしています。
Aエラー、警告は0です。
B一回目に実行した後、また実行すると
「1>LINK : fatal error LNK1168: ファイル C:\Users\○○\Desktop\マップ表示\Debug\マップ表示.exe を開いて書き込むことができません。」
というエラーが出る。
ソースです↓
#include "DxLib.h"
#define TATE 480
#define YOKO 640
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ; // ウインドウモードに変更
if( DxLib_Init() == -1 ) return -1;
int data[TATE][YOKO];
int image[480];
int i,j;
//二次元配列dataの初期化
for(i=0;i<TATE;i++){
for(j=0;j<YOKO;j++){
data[i][j] = 0;
}
}
//画像の分割読み込み
LoadDivGraph("mori.bmp",480,30,16,16,16,image);
//マップを表示する
for(i=0;i<TATE;i++){
for(j=0;j<YOKO;j++){
if(data[i][j]==0){
DrawGraph(0,0,image[0],TRUE);
}
}
}
WaitKey();
DxLib_End();
return 0;
}
☆自分について
C言語の知識は、ポインタ、構造体、ファイルの作成の基礎知識はあります。
C++は全く触れてません。
DXは使い始めて1ヶ月ぐらいです。
OSはWindows7です。
Visual C++ Express Editionを使っています。
よろしくお願いします!!
490ポイント を手に入れた。
|
|
|
Name: ikara ..ぴよぴよ(263ポイント)
Date: 2010/09/15(水) 21:07
No:61806
|
|
Title: C# ストアドプロシージャのコールについて
|
|
お世話になります。
sqlserver management studioで下記のような実行をした場合
DECLARE @vvv1 varchar(200)
DECLARE @vvv2 varchar(200)
SET @vvv2 = 'VVVVVVVVVVVVVVVVV'
SET @vvv1 = @vvv2
exec helloworld3 @vvv1
これと同じようなことをC#で行いたいです。
要はアプリケーションからストアドプロシージャをcallした際のTRCファイルを取得し、
TRCファイルの解析を行いたいのですが、C#に疎いもので、どうにもうまくいきません。
申し訳ありません、ご教示いただけないでしょうか。
64ポイント を手に入れた。
|
|
|
Name: エデリュス ..かけだし(2,344ポイント)
Date: 2010/09/10(金) 20:59
No:61434
|
|
Title: 斜方投射とバウンド
|
|
物理で習った斜方投射とゲームプログラミングの館を参考に東方の旧作霊異伝っぽいゲームを作ってみようかと思ったのですが、いくつか問題があったので質問させていただきます。
1:角度をつけて斜方投射をしたいのですがゲームプログラミングの館の28. ジャンプの考え方2(物理)
と29. 跳ね返りの考え方(物理) を参考にこのように書いてみました。
#include "DxLib.h"
#include <math.h>
#define e 0.900
#define g 9.807
#define v 1.000
#define PI 3.14159265358979323846
#define y_max 2.000
int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP,LPSTR lpC, int nC){
int image[8];
char Key[256];
int x,y,time1,time2,flag=0,i,j;
int a=0;
int hx=0;
int hy=0;
int count=0;
int gameclrea=0;
double t,v0;
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
SetDrawScreen( DX_SCREEN_BACK ) ; //描画先を裏画面に設定
LoadDivGraph( "onmyou.png" , 8 , 4 , 2 , 24 , 24 , image );//画像を分割してimage配列に保存
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了
ClearDrawScreen(); // 裏画面のデータを全て削除
GetHitKeyStateAll( Key ) ; // すべてのキーの状態を得る
if( Key[ KEY_INPUT_RETURN ] == 1 ){ //エンターが押されたら
time1 = GetNowCount(); //time1にエンターが押された時の時間を格納
flag=1; //飛び上がりフラグを立てる。
}
if(flag==1){
time2=GetNowCount();
v0= sqrt ( 2.000 * g * y_max);
t = (double)(time2-time1)/1500.000;
x = t*v0*40;
for(i=0;i<j;i++) //j回跳ね返った時の初速度
v0*=e; //eは反発係数
y = (int)((v0*t-0.500*g*t*t)*320.000/y_max);
a=a+1;
if(a>3){
a=0;
}
hx=610-x;
hy=380-y;
if(y>=-70)
DrawGraph(hx, hy , image[a] , TRUE ) ;
else{
time1=GetNowCount();
j++;
}
if( Key[ KEY_INPUT_ESCAPE ] == 1 ){
DxLib_End();
return 0; //Escボタンが押されたらend
}
ScreenFlip(); // 裏画面データを表画面へ反映
}
}
}
これを実行するとしっかり斜方投射するのですがその場でバウンドせず戻って再び斜方投射します。
自分はxy位置が原因だと思うのですがうまくいきません。
それと28. ジャンプの考え方2(物理)はsinやcosで計算してませんがやはり三角関数を使うべきなのでしょうか?その場合はラジアンで角度を出しx、yそれぞれの式にsin()cos()を入れるのでしょうか? 
1,274ポイント を手に入れた。
|
|
|
|
Name: Tatu ..熟練のプログラマー(44,308ポイント)
Date: 2010/09/10(金) 22:08
No:61460
|
|
Title: Re:斜方投射とバウンド
|
|
ボールの移動については速度用の変数を用意し、
速度を計算してその値を現在の座標に足すというやり方をすればよいのではないでしょうか。
速度についてはxy座標で扱い、角度は使わなくてもよいでしょう。
以前、「東方靈異伝」風のゲームを作成し、公開したことがあります。
作成している時は「龍神録プログラミングの館」のページとプロジェクトを見ながら作っていました。
エデリュスさんも「龍神録プログラミングの館」を参考にしてみてはいかがですか?
2倍のポイントを手に入れた! 434ポイント を手に入れた。
|
|
|
|
|
Name: エデリュス ..かけだし(2,454ポイント)
Date: 2010/09/11(土) 16:51
No:61508
|
|
Title: Re:斜方投射とバウンド
|
|
>>Tatuさん
ありがとうございます。おかげでさまでバウンドに成功しました。
これからは龍神録プログラミングの館も参考にしてみます。
>>以前、「東方靈異伝」風のゲームを作成し、公開したことがあります。
もう公開はおわってますか?
できればプレイしたいのですが・・・
110ポイント を手に入れた。
|
|
|
|
|
Name: エデリュス ..入門者(2,552ポイント)
Date: 2010/09/12(日) 15:50
No:61603
|
|
Title: Re:斜方投射とバウンド
|
|
>>Tatuさん
アップロードありがとうございます。
早速プレイさせていただきました。
キクリっぽいのが鬼門でした。
ブロックをエクセルで制御してるんですね。参考になります。
質問なんですが壁のバウンドって床と同じですか?
98ポイント を手に入れた。
|
|
|
|
|
Name: Tatu ..熟練のプログラマー(44,664ポイント)
Date: 2010/09/12(日) 20:53
No:61623
|
|
Title: Re:斜方投射とバウンド
|
|
壁というのが左右の端を指すのであればほぼ同じです。
細長いブロックのことならぶつかったかどうかを調べた後に
縦横どちらでぶつかったかの判定を行っています。
ソースを見たところ、
ぶつかったときにボールの座標を移動前のときの値に戻してから
左右の端では横方向の速度に-1をかけ、
上の端では縦方向の速度に-1をかけ、
床では縦方向の速度に-0.8をかけていました。
壊れないブロックではぶつかったと判断された方向の速度に-1をかけていました。
205ポイント を手に入れた。
|
|
|
|
|
Name: エデリュス ..入門者(2,607ポイント)
Date: 2010/09/15(水) 20:19
No:61802
|
|
Title: Re:斜方投射とバウンド
|
|
>>Tatuさん
ありがとうございます。返信が遅れてすみません。
なんとか壁のバウンドもできるようになりました。
本当にありがとうございました。
55ポイント を手に入れた。
|
|
|
|
Name: つつ# ..ぴよぴよ(29ポイント)
Date: 2010/09/15(水) 15:10
No:61782
|
|
Title: クラス内で構造体宣言
|
|
クラス内で構造体を宣言することは可能なんですか??
どう作れば良いのですか?
29ポイント を手に入れた。
|
|
|
|
Name: へろり ..プログラマー(38,510ポイント)
Date: 2010/09/15(水) 15:14
No:61783
|
|
Title: Re:クラス内で構造体宣言
|
|
実際に書いてみればいいですよ。 間違っていたらコンパイラが教えてくれます。
class HOGE{
private:
struct BAA{
int foo;
}baa;
};
87ポイント を手に入れた。
|
|
|
|
|
Name: つつ ..かけだし(2,088ポイント)
Date: 2010/09/15(水) 15:20
No:61784
|
|
Title: Re:クラス内で構造体宣言
|
|
書くことには書いてるんですけどね....
実体をどこで作ればいいんですか???
public内で作れないんですけど..... 
36ポイント を手に入れた。
|
|
|
|
|
Name: つつ# ..ぴよぴよ(0ポイント)
Date: 2010/09/15(水) 16:11
No:61787
|
|
Title: Re:クラス内で構造体宣言
|
|
ookami >>: 今ひとつしっくりこなかったんですが。
今わこうゆう状態になってます。
private:
//変数
struct PLAYERSTATE {
double Player_x; // プレイヤー座標X
double Player_y; // プレイヤー座標Y
int Speed; //1ターンあたりの移動ドット数
int dir;
int JumpFlag; // ジャンプフラグ
int JumpPower; // ジャンプパワー
int animation; // アニメーション
int CharaGraph[10][10]; // プレイヤー画像ハンドル
};
PLAYERSTATE PLS;
public:
}
構造体の実体をどこで宣言すれば良いのか分からない状態です.
171ポイント を落としてしまった。
|
|
|
|
|
Name: ookami ..熟練のプログラマー(52,472ポイント)
Date: 2010/09/15(水) 16:38
No:61788
|
|
Title: Re:クラス内で構造体宣言
|
|
構造体の実体は、
PLAYERSTATE PLS;
で、宣言されていると思いますよ?
そのクラスを使っている側のソースとか、
現状、どんな問題があるか、
もうちょい詳しく教えてもらっていいですか?
68ポイント を手に入れた。
|
|
|
|
|
Name: つつ# ..ぴよぴよ(38ポイント)
Date: 2010/09/15(水) 16:44
No:61789
| 解決!
|
Title: Re:クラス内で構造体宣言
|
|
宣言場所は間違ってないみたいですね。
なんか急に使えるようになりました。 
38ポイント を手に入れた。
|
|
|
|
|
Name: ookami ..熟練のプログラマー(52,519ポイント)
Date: 2010/09/15(水) 16:48
No:61790
|
|
Title: Re:クラス内で構造体宣言
|
|
> public内で宣言したPLSを使おうとすると
その時のソースと、
> PLS.が正しく使われていないと言われて
というのは、コンパイルエラーだと思いますので、
それぞれ貼ってもらっていいですか?
上で示されているソースは、PLSはprivateで宣言されています。
-- 追記
編集で解決になったようですねw
後で見た人が 参考になると思いますので、
結局何が問題だったのか、書いてもらえると助かります。 
47ポイント を手に入れた。
|
|
|
|
Name: ななしん ..ぴよぴよ(90ポイント)
Date: 2010/09/15(水) 11:20
No:61775
|
|
Title: プログラミングの関連付け?
|
|
はじめまして。
最近ゲームプログラミングを始めてこのサイトに出会いました
質問なんですが、ソースファイルを複数作成して、関連を持たせるにはどうしたらよいのでしょうか?
たとえば、タイトル画面と次のゲーム画面を別のソースファイルで作成しようとすると
すでに定義されているため使えませんというエラーが表示されてしまいます。
ほかのサイトも見ているのですが、いまいち理解できません
90ポイント を手に入れた。
|
|
|
|
Name: fatens ..上級者(19,270ポイント)
Date: 2010/09/15(水) 12:13
No:61776
|
|
Title: Re:プログラミングの関連付け?
|
|
>たとえば、タイトル画面と次のゲーム画面を別のソースファイルで作成しようとすると
>すでに定義されているため使えませんというエラーが表示されてしまいます。
それらのソースやエラーメッセージなどを書いていただかないと、
こちらにはどういう状況なのか分かりません。
使用しているライブラリやコンパイラなどについても書いてください。
111ポイント を手に入れた。
|
|
|
|
|
Name: ななしん ..ぴよぴよ(798ポイント)
Date: 2010/09/15(水) 12:49
No:61777
|
|
Title: Re:プログラミングの関連付け?
|
|
説明不足ですみません
#include "DxLib.h"
int GetHitKeyStateAll_2(int KeyStateBuf[]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key[i]==1) KeyStateBuf[i]++;
else KeyStateBuf[i]=0;
}
return 0;
}
void char_disp(int White,int y){
DrawString( 180 , y , "■" , White );
DrawString( 200 , 240 , "はじめから" , White );
DrawString( 200 , 280 , "続きから" , White );
DrawString( 200 , 320 , "終わり" , White );
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int Key[256];
int White , y=240; //色とy座標の宣言
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
White = GetColor( 255 , 255 , 255 ) ; //色の取得
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
char_disp(White,y); // 文字を描画
if( Key[KEY_INPUT_DOWN]==1 ||( Key[KEY_INPUT_DOWN]%5==0 && Key[KEY_INPUT_DOWN]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
y+=40;
if(y==360) // y座標が320なら(選択が一番下なら)
y=240; // 選択座標を一番上に
}
else if( Key[KEY_INPUT_UP]==1 ||( Key[KEY_INPUT_UP]%5==0 && Key[KEY_INPUT_UP]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
y-=40;
if(y==200) // y座標が160なら(選択が一番下なら)
y=320; // 選択座標を一番下に
}
ScreenFlip();//裏画面反映
}
DxLib_End();
return 0;
}
ともうひとつサンプルを作ったのですが
WinMain@16 は既に gazou.obj で定義されています。
game-test\Debug\game-test.exe : fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。
というエラーがでてしまいます
708ポイント を手に入れた。
|
|
|
|
|
Name: ななしん ..ぴよぴよ(740ポイント)
Date: 2010/09/15(水) 14:26
No:61781
|
|
Title: Re:プログラミングの関連付け?
|
|
わかりました。
御説明ありがとうございました
自分でもごちゃごちゃしてるみたいなんで一度整理して始めたいと思います
58ポイント を落としてしまった。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(576,854ポイント)
Date: 2010/09/13(月) 22:11
No:61676
|
|
Title: Re:iPhoneアプリ開発 CSVの読み込み
|
|
>csvLoadクラスからオブジェクトを作ってみたのですがLoadが呼べません・・・。
csvLoadクラスは Objective-Cのオブジェクトなので csv->Load()とは呼べません。
[csv Load:path]
といった Objective-C風の呼び出しでやってみて下さい。
>またRootViewはどこで生成すればよいのでしょうか?
従来通り didFinishLaunchingWithOptionsでいいと思います。
ついでなので前回のときにこちらで作っていたサンプルから抜粋したものを載せておきます。
(ちゃんとテストはしていないので間違っているかもしれませんし、コピペそのままでは動かないと
思いますので、雰囲気ということで)
http://codepad.org/k6AgjrsG
212ポイント を手に入れた。
|
|
|
|
|
Name: 健史 ..かけだし(1,209ポイント)
Date: 2010/09/14(火) 03:41
No:61688
|
|
Title: Re:iPhoneアプリ開発 CSVの読み込み
|
|
サンプルソースまでありがとうございます!!
イメージが湧きました。
好きな値で初期化できる様なRootViewをタブの数だけ作れということですよね?
[csv Load:path] で問題なく動きました。
そういうことだったのですね・・・。
ありがとうございます。
私のソースではRootViewを自分で書いていないのに勝手にセットされている気がします。
didFinishLaunchingWithOptionsやtestAppDelegate.mで記載していないのに
テーブルが表示されております。
http://www1.axfc.net/uploader/Sc/so/153097.zip
pass:test
2倍のポイントを手に入れた! 486ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(577,242ポイント)
Date: 2010/09/14(火) 23:12
No:61759
|
|
Title: Re:iPhoneアプリ開発 CSVの読み込み
|
|
>didFinishLaunchingWithOptionsやtestAppDelegate.mで記載していないのに
>テーブルが表示されております。
既にお気付きだとは思いますが、xibでそう指定されているから、ですね。
>ただデータが出力されてくれません。
そりゃあ cellForRowAtIndexPathでセットしていないんで……。
122ポイント を手に入れた。
|
|
|
|
|
Name: 健史 ..かけだし(1,268ポイント)
Date: 2010/09/15(水) 02:19
No:61767
|
|
Title: Re:iPhoneアプリ開発 CSVの読み込み
|
|
出来ました!!
IBが原因だったのですか・・・
気がついてませんでした・・・。
ありがとうございます。
ご迷惑をおかけいたしました。
ありがとうございました。
86ポイント を落としてしまった。
|
|
|
|
Name: フィリップ ..ぴよぴよ(78ポイント)
Date: 2010/09/09(木) 15:05
No:61355
|
|
Title: OpenGL ESでTTFを読み込んで使用する
|
|
OpenGL ES(2.0)を使ってiPhoneで動くゲームを開発しております。
年間登録もしており幾つか作品を公開しております。
今回、新しく作るゲーム画面でttf(フォントファイル)を読み込んで
それを反映させるようなことをしたいです。
色々と調べてみたのですがそれらしい記事が見当たりませんでした。
ttfファイルから文字を表示させるようなことはOpenGLでは出来ないのでしょうか?
チュートリアル等で使うので出来ればフォントを読み込んで使いたいです。
また今まで文字はベタでPNGファイルを用意していたので
ttfを使えないのでしたら搭載されているフォントを使い文字列を描画できないでしょうか?
添付させて頂いたファイルは現在使っているベタ書きしたPNGファイルです。
78ポイント を手に入れた。
|
|
|
|
Name: フィリップ ..ぴよぴよ(35ポイント)
Date: 2010/09/11(土) 01:17
No:61477
|
|
Title: Re:OpenGL ESでTTFを読み込んで使用する
|
|
連絡が遅くなりすみません。
ご回答ありがとうございます。
>>NSStringが拡張されて専用の表示メソッドが追加されていますので
これは添付して頂いたURLの物を使うのですよね?
添付して頂いたものを使っているのですがエラーが出てしまいます。
多分、インクルードするファイルが間違えていると思うのですが
どれを読み込めばよいのでしょうか?
35ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(576,335ポイント)
Date: 2010/09/11(土) 01:49
No:61479
|
|
Title: Re:OpenGL ESでTTFを読み込んで使用する
|
|
>添付して頂いたものを使っているのですがエラーが出てしまいます
サンプルのプロジェクトは動かしてみましたか?
で、どう書いたら、どの段階でどういうエラーが出たのですか?
>どれを読み込めばよいのでしょうか
?
ひょっとして自分のプロジェクトに組み込むソースがどれだかわからない、ということでしょうか?
104ポイント を手に入れた。
|
|
|
|
|
Name: フィリップ ..かけだし(1,001ポイント)
Date: 2010/09/11(土) 03:06
No:61482
|
|
Title: Re:OpenGL ESでTTFを読み込んで使用する
|
|
回答ありがとうございます。
サンプルは動かしました。
3種類の文字がそれぞれの色で出ているやつですよね?
それをもとに実装しております。
自分のプロジェクトにClasses内にあるFontLabelフォルダをすべて追加し
ソースを下記の様に修正しております。
>>エラーについて
記載したほうがわかりやすかったですね・・・。
レンダーをしているソースにFontLabelという型を使うとエラーが出てしまいます。
〜ES1Renderer.mm:117: error: 'FontLabel' was not declared in this scope
// OpenGLAppDelegate.m
// OpenGL
#import "OpenGLAppDelegate.h"
#import "EAGLView.h"
#import "FontManager.h"
@implementation OpenGLAppDelegate
@synthesize window;
@synthesize glView;
- (void) applicationDidFinishLaunching:(UIApplication *)application{
[[FontManager sharedManager] loadFont:@"Abduction"];
}
//////////////////////////////////////////////////
// レンダーをしているソース
//////////////////////////////////////////////////
FontLabel *label = [[FontLabel alloc] initWithFrame:CGRectMake(10, 10, 0, 0) fontName:@"Abduction" pointSize:40.0f];
label.textColor = [UIColor magentaColor];
label.text = @"lorem ipsum";
[label sizeToFit];
label.backgroundColor = nil;
label.opaque = NO;
>>エイバースの中の人 : iPhoneのOpenGLで文字を書く
私のソースではGLuint型というのでテクスチャを用意し
GLuint型専用の描画関数を使っております。
(openglで作るiphone sdkゲームプログラミングという本に書いてあったもの)
もしフォント専用のテクスチャを作るとした場合、添付して頂いたURLの様な
構造体を新規に用意して専用の描画関数を作らなければいけないのでしょうか?
出来ればDXライブラリのDrawFormatString関数の様に使えるようにしたいです。
※%d等の可変引数?は実装できなそうなので
DrawString( int 左端X, int 左端Y, NSString* 表示する文字列)のようにして便利に文字を表示したいです。
OpenGLの理解度としてお察しかとは思いますが殆ど無知です。
プログラム能力としましてはDXライブラリ等を使えば一通りの物を作れますが
自分でライブラリの改変等は全くできません。
質問ばかりで申し訳ないのですがどうか教えては頂けないでしょうか?
923ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(576,642ポイント)
Date: 2010/09/11(土) 21:58
No:61526
|
|
Title: Re:OpenGL ESでTTFを読み込んで使用する
|
|
>FontLabelという型を使うとエラー
FontLabelは FontLabel.hで定義されており、FontManager.hからは importされていないので
FontLabel.hを importして下さい。
>構造体を新規に用意して専用の描画関数を作らなければいけないのでしょうか?
別に構造体である必要はないですが、専用の描画関数……DXライブラリのDrawFormatString相当の……は
作らないと表示はできません。
一応先のHPの処理を理解すればそれを作ることは可能なはずです。
>OpenGLの理解度としてお察しかとは思いますが殆ど無知です
それはなかなか厳しいですね。
OpenGLは DXライブラリのように簡単にはいかないので、そこは勉強あるのみです。
171ポイント を手に入れた。
|
|
|
|
|
Name: フィリップ ..かけだし(2,353ポイント)
Date: 2010/09/13(月) 11:19
No:61642
|
|
Title: Re:OpenGL ESでTTFを読み込んで使用する
|
|
連絡が遅くなってしまいすみません。
インポートしたところエラーが消えました。
ありがとうございます。
フォントの読み込みは出来てそうなのですが
ここから文字列をテクスチャにすることがどうしても出来ません・・・。
OpenGLのサイトをみては見たのですが
エラーがとれません・・・。
以下が現在のソースです。
m_p_font_textureを用意した構造体で宣言する必要があると思うのですが宣言するとエラーが増えてしまいます。
またFONT_TEXTURE_MIPMAP_SIZE[i]やtext等の値が不明なオブジェクトが出て来てしまいました。
これは自分で定数を入れろということなのでしょうか?
質問ばかりで申し訳ないです。
// Init部分 一回のみ読み込み
FontLabel *label = [[FontLabel alloc] initWithFrame:CGRectMake(10, 10, 0, 0) fontName:@"Abduction" pointSize:40.0f];
label.textColor = [UIColor magentaColor];
label.text = @"lorem ipsum";
[label sizeToFit];
label.backgroundColor = nil;
label.opaque = NO;
// 以下ループで描画処理
// NSString *text = [[NSString alloc] init];
// struct FontTextureMipmap m_p_font_texture;
//テクスチャサイズを定義する
// int s=FONT_TEXTURE_MIPMAP_SIZE[i];
// m_p_font_texture->texture.width=s;
// m_p_font_texture->texture.height=s;
// テクスチャを作成する
// glGenTextures(1, &(m_p_font_texture->texture.id));
// テクスチャをバインドする
// glBindTexture(GL_TEXTURE_2D, m_p_font_texture->texture.id);
// テクスチャの設定を行う
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//テクスチャのRGBAデータの配列を確保する
// m_p_font_texture->data = (GLubyte *)malloc(m_p_font_texture->texture.width * m_p_font_texture->texture.height * 4);
//テクスチャデータをVRAM上に転送し領域を確保する
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_p_font_texture->texture.width,m_p_font_texture->texture.height,0, GL_BGRA, GL_UNSIGNED_BYTE, m_p_font_texture->data);
//文字描画用のコンテキストを作成する
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// m_p_font_texture->_context = CGBitmapContextCreate(m_p_font_texture->data, m_p_font_texture->texture.width, m_p_font_texture->texture.height, 8, m_p_font_texture->texture.width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
//フォントを確保する
m_font = [UIFont systemFontOfSize:14];
//実際の描画サイズを取得
// CGSize size=[text sizeWithFont:m_font constrainedToSize:CGSizeMake(sx,512) lineBreakMode:UILineBreakModeWordWrap];
// m_p_font_texture->texture.original_width=size.width;
// m_p_font_texture->texture.original_height=size.height;
//文字画像は上下反転しているので描画時にUV反転する
//また、クリッピングエリアも反転するので注意
// 文字を描画する
memset(m_p_font_texture->data,0,m_p_font_texture->texture.width*m_p_font_texture->texture.height*4);
UIGraphicsPushContext(m_p_font_texture->_context);
// UIColor *color=[UIColor colorWithRed:r/255.0f green:g/255.0f blue: b/255.0f alpha:1.0f];
// [color set];
// [text drawInRect:CGRectMake(0,m_p_font_texture->texture.height-m_p_font_texture->texture.original_height,sx,m_p_font_texture->texture.original_height) withFont:m_font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];
UIGraphicsPopContext();
// テクスチャをバインドする
// glBindTexture(GL_TEXTURE_2D, m_p_font_texture->texture.id);
// テクスチャを更新する
// glTexSubImage2D(GL_TEXTURE_2D, 0, 0,m_p_font_texture->texture.height-m_p_font_texture->texture.original_height, m_p_font_texture->texture.width,m_p_font_texture->texture.original_height, GL_RGBA, GL_UNSIGNED_BYTE, m_p_font_texture->data);
}
1,352ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(577,052ポイント)
Date: 2010/09/13(月) 22:16
No:61677
|
|
Title: Re:OpenGL ESでTTFを読み込んで使用する
|
|
>これは自分で定数を入れろということなのでしょうか?
はい。
基本コピペそのままでうまくいくコードなんてそうそう転がっているものじゃないので、
そのあたりは自前で情報をそろえてあげる必要があります。
とりあえず FONT_TEXTURE_MIPMAP_SIZE[i]の代入先の sには 256でも入れておけばまずは十分でしょう。
2倍のポイントを手に入れた! 198ポイント を手に入れた。
|
|
|
|
|
Name: フィリップ ..入門者(2,644ポイント)
Date: 2010/09/14(火) 03:10
No:61685
|
|
Title: Re:OpenGL ESでTTFを読み込んで使用する
|
|
ご回答ありがとうございます。
何とかエラーが出ないで改変することが出来ました。
本当にありがとうございます。
このテクスチャを表示してみたのですが何も表示できませんでした。
m_p_font_texture.texture.idを描画すればよいという訳ではないのでしょうか?
// Init部分 一回のみ読み込み
FontLabel *label = [[FontLabel alloc] initWithFrame:CGRectMake(10, 10, 0, 0) fontName:@"Abduction" pointSize:40.0f];
label.textColor = [UIColor magentaColor];
label.text = @"lorem ipsum";
[label sizeToFit];
label.backgroundColor = nil;
label.opaque = NO;
// 以下ループで描画処理
NSString *text = @"あいうえお";
int sx = 0;
//テクスチャサイズを定義する
int s=256;
m_p_font_texture.texture.width=s;
m_p_font_texture.texture.height=s;
// テクスチャを作成する
glGenTextures(1, &(m_p_font_texture.texture.id));
// テクスチャをバインドする
glBindTexture(GL_TEXTURE_2D, m_p_font_texture.texture.id);
// テクスチャの設定を行う
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
//テクスチャのRGBAデータの配列を確保する
m_p_font_texture.data = (GLubyte *)malloc(m_p_font_texture.texture.width * m_p_font_texture.texture.height * 4);
//テクスチャデータをVRAM上に転送し領域を確保する
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_p_font_texture.texture.width,m_p_font_texture.texture.height,0, GL_BGRA, GL_UNSIGNED_BYTE, m_p_font_texture.data);
//文字描画用のコンテキストを作成する
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
m_p_font_texture._context = CGBitmapContextCreate(m_p_font_texture.data, m_p_font_texture.texture.width, m_p_font_texture.texture.height, 8, m_p_font_texture.texture.width * 4, colorSpace, kCGImageAlphaPremultipliedLast);
//フォントを確保する
m_font = [UIFont systemFontOfSize:14];
//実際の描画サイズを取得
CGSize size=[text sizeWithFont:m_font constrainedToSize:CGSizeMake(sx,512) lineBreakMode:UILineBreakModeWordWrap];
m_p_font_texture.texture.original_width=size.width;
m_p_font_texture.texture.original_height=size.height;
//文字画像は上下反転しているので描画時にUV反転する
//また、クリッピングエリアも反転するので注意
// 文字を描画する
memset(m_p_font_texture.data,0,m_p_font_texture.texture.width*m_p_font_texture.texture.height*4);
UIGraphicsPushContext(m_p_font_texture._context);
// UIColor *color=[UIColor colorWithRed:r/255.0f green:g/255.0f blue: b/255.0f alpha:1.0f];
UIColor *color=[UIColor colorWithRed:255 green:255 blue:255 alpha:1.0f];
[color set];
[text drawInRect:CGRectMake(0,m_p_font_texture.texture.height-m_p_font_texture.texture.original_height,sx,m_p_font_texture.texture.original_height) withFont:m_font lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentLeft];
UIGraphicsPopContext();
// テクスチャをバインドする
glBindTexture(GL_TEXTURE_2D, m_p_font_texture.texture.id);
// テクスチャを更新する
glTexSubImage2D(GL_TEXTURE_2D, 0, 0,m_p_font_texture.texture.height-m_p_font_texture.texture.original_height, m_p_font_texture.texture.width,m_p_font_texture.texture.original_height, GL_RGBA, GL_UNSIGNED_BYTE, m_p_font_texture.data);
291ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(577,418ポイント)
Date: 2010/09/14(火) 23:47
No:61763
|
|
Title: Re:OpenGL ESでTTFを読み込んで使用する
|
|
>このテクスチャを表示してみたのですが何も表示できませんでした。
FontLabelは導入していないので省きましたが、それ以下のコードはそのままコピペしてもちゃんと表示されましたよ。
描画周りを見直してみて下さい。
2倍のポイントを手に入れた! 176ポイント を手に入れた。
|
|
|
|
Name: dic ..比類無きプログラマー(96,164ポイント)
Date: 2010/09/14(火) 19:54
No:61733
|
|
Title: ウィンドウ(ボタン)を配置するがFlipで上書きされる
|
|
自作のDirectXライブラリを使用してます
CreateWindow() 関数でボタンクラスを指定してボタンを作成
表示までできたのですが、DirectX の Flip処理をすると
ボタンが描画された状態のところを上書きしてしまうので
ボタンが見えない状態になってしまいます
どこに配置しているか文字で表してます
ここをクリックすると一瞬ボタンウィンドウが見えるのでうまくいっているようですが
DirectDraw の Flip関数を使うと画面全体を描画するので
どうしてもボタンが消えてしまいます
どのようにしたらボタンが描画されているように見えるのでしょうか?
どのようなものか下に実行ファイルを置いておきます
http://www1.axfc.net/uploader/Sc/so/153278
(送付ファイルと同じものです)
m_hwnd = CreateWindow( "BUTTON", "ゴシック", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
m_x, m_y, 100, 30, hwndApp, (HMENU)100, hInstApp, NULL );
としてボタンを作成してますが その後に呼び出される画面再描画関数
DEF_DXDRAW->Flip( hwndApp );
で上書きしてしまうのです
どうしてもできない場合は独自のボタンクラスを作り
これに文字を描画しようと考えています 
40ポイント を落としてしまった。
|
|
|
|
Name: シエル [URL] ..比類無きプログラマー(76,803ポイント)
Date: 2010/09/14(火) 20:21
No:61745
|
|
Title: Re:ウィンドウ(ボタン)を配置するがFlipで上書きされる
|
|
実行しましたが、どこにボタンがあるのかわかりませんでしたw
DirectDrawだとちょっと対応方法が分かりませんね。
ちなみに親ウィンドウのウィンドウスタイルにWS_CLIPCHILDRENを追加してみても駄目でしょうか?
79ポイント を手に入れた。
|
|
|
|
|
Name: 御津凪 [URL] ..ハッカー(149,171ポイント)
Date: 2010/09/14(火) 20:30
No:61747
|
|
Title: Re:ウィンドウ(ボタン)を配置するがFlipで上書きされる
|
|
DirectX系の描画は作成時に指定したウインドウハンドルの描画範囲を占有して描画します。
そのため、そのウインドウにコントロールなど(子ウインドウ)があっても、全て丸ごと上書きされます。
これを回避する方法は原則としてありません。
(Flip後に強制的に描画させることはできますが、チラつきますし、CPUの負担が大きくなります)
素直に自作UIを作るなりした方が早いですよ。
111ポイント を手に入れた。
|
|
|
|
|
Name: dic ..比類無きプログラマー(96,535ポイント)
Date: 2010/09/14(火) 22:15
No:61757
| 解決!
|
Title: Re:ウィンドウ(ボタン)を配置するがFlipで上書きされる
|
|
>シエルさん
WS_CLIPCHILDRENをウィンドウ作成時のフラグに追加してもダメみたいでした
クリックするのは左下の文字「戦略」「基地」というところです
>御津凪さん
>これを回避する方法は原則としてありません
やはりそうですか
市販ゲームなども独自のUIを作っているので市販されてるゲームのUIなどを
参考します
助言ありがとうございました
122ポイント を手に入れた。
|
|
|
|
Name: Ultimate ..上級者(15,497ポイント)
Date: 2010/09/14(火) 17:16
No:61704
|
|
Title: 画像の当たり判定
|
|
単刀直入ですが、弾幕を作っているのですが、中央の固定敵の上を自機が通らないようにしたいのですが、画像の上に自機のx,yが来ないようにする簡単な方法はありますか?
今後敵が増えるので、いちいちifでは大変なので、なにか方法があれば教えてください。
2倍のポイントを手に入れた! 136ポイント を手に入れた。
|
|
|
|
Name: DVDM [URL] ..熟練のプログラマー(60,747ポイント)
Date: 2010/09/14(火) 18:36
No:61713
|
|
Title: Re:画像の当たり判定
|
|
>>Ultimateさん
> 今後敵が増えるので、いちいちifでは大変なので、なにか方法があれば教えてください。
中央固定という事なので、
今後敵が増えた時も中央より上に行けないようにするのであれば
自機のY座標が中央よりも下に居れば移動できるようにしてみては如何でしょうか。
79ポイント を手に入れた。
|
|
|
|
Name: べの ..ぴよぴよ(224ポイント)
Date: 2010/09/14(火) 19:11
No:61720
|
|
Title: scanf文について
|
|
はじめまして。
C言語の勉強を始めて2日目になります。
http://wisdom.sakura.ne.jp/programming/c/c7.html
↑こちらのサイトを参考に進めているのですが、
このページの例にあるswitch文の定数式が整数(partAとします)、文字定数(partBとします)のとき
partAのみの場合 →正常動作
partBのみの場合 →正常動作
partA+partBの場合 →不具合
partB+partAの場合 →正常動作
となってしまいます。
具体的には、partBがpartAの後ろにくる場合のみ、scanf("%c" , &ch); が実行されず、defaultが返ってきてしまいます。
scanfを記述する順序によって問題が発生しているのでしょうか?
問題点、解決法をご教授ください。
宜しくお願い致します。
■環境
WindowsXP Home SP3
Microsoft Visual C++ 2010 Express
■ソース
#include <stdio.h>
int main()
{
char ch;
int var;
/* partA ここから */
printf("あなたは猫耳が好きですか?\n");
printf("はい = 1\tいいえ = 2\t兎耳のほうが… = 3\n");
scanf("%d",&var);
switch (var) {
case 1:
printf("同士よ、共に全宇宙を猫耳に染めようぞ!\n\n");
break;
case 2:
printf("それじゃアキバは歩けないぜ、旦那\n\n");
break;
case 3:
printf("ウサギちゃんか…耳で空飛ぶんだぞ!\n\n");
break;
default:
printf("指定した数を選択してください\n\n");
}
/* partA ここまで */
/* partB ここから */
printf("今日の奈美はどこかおかしい\n突然不安にかられた僕は…\n\n");
printf("A\t「奈美ぃーー!どこだ、返事をしろー!!」\n");
printf("\t僕は奈美を必死で探した\n\n");
printf("B\t「猫耳ィー!どこだ、でじこーーー!!」\n");
printf("\t僕は男のロマンを叫んだ\n");
switch(ch) {
case 'A':
printf("まぁ、何をしたって屋敷は燃えるんだよね…\n僕はプレイヤーとして諦めた\n\n");
break;
case 'B':
printf("やはりこの世で最も美しいのは猫耳だ\n今日、改めてそれを確信した\n\n");
break;
default:
printf("AかBを選択してにょ\n\n");
}
/* partB ここまで */
getchar();
return 0;
}
224ポイント を手に入れた。
|
|
|
|
Name: べの ..ぴよぴよ(764ポイント)
Date: 2010/09/14(火) 19:38
No:61730
|
|
Title: Re:scanf文について
|
|
>パコネコさん
>Dixgさん
すみません、説明文に載せるときにコピーではなくカットしてしまったようです・・・
こんな初歩的なミスをするとは・・
位置はPartBのswitch文の直前になります。
ご回答ありがとうございます。
入力が残っているということがあるのですね。
なぜそういうことが起こるのかについては調べてみようと思います。
ありがとうございました。
-----------------------
折角なので、タイトルとは関係ありませんが便乗してもうひとつ質問させてください。
上記のソースでたとえると、switch文のdefault時には再度入力をやりなおさせるのが普通だと思うのです。
素人考えではGOTO(のようなもの)を使いpartの頭まで戻せばよいと思っていたのですが
Cでは通常GOTOは使ってはいけないと書いてありました。
この場合はwhileを使い以下のような処理でよいのでしょうか。一応正常に動作はします。
よろしくお願い致します。
/* partA ここから */
while (1) {
printf("あなたは猫耳が好きですか?\n");
printf("はい = 1\tいいえ = 2\t兎耳のほうが… = 3\n");
scanf("%d",&var);
switch (var) {
case 1:
printf("同士よ、共に全宇宙を猫耳に染めようぞ!\n\n");
break;
case 2:
printf("それじゃアキバは歩けないぜ、旦那\n\n");
break;
case 3:
printf("ウサギちゃんか…耳で空飛ぶんだぞ!\n\n");
break;
default:
printf("指定した数を選択してください\n\n");
continue;
}
break;
}
/* partA ここまで */
540ポイント を手に入れた。
|
|
|
|
|
Name: たかぎ [URL] ..ハッカー(227,506ポイント)
Date: 2010/09/14(火) 19:54
No:61734
|
|
Title: Re:scanf文について
|
|
> 素人考えではGOTO(のようなもの)を使いpartの頭まで戻せばよいと思っていたのですが
> Cでは通常GOTOは使ってはいけないと書いてありました。
再試行に(GOTOではなく)gotoを使うのは、わりと普通のことです。
29ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) [URL] ..ウィザード(1,276,488ポイント)
Date: 2010/09/14(火) 20:08
No:61741
|
|
Title: Re:scanf文について
|
|
2重ループから抜けたり、関数の中で終了処理をあちこちでする必要がある場合など、
gotoを使う事はありますね。
ただ、C言語の参考サイト、参考書にはgotoは使わないようにと書いてあると思います。
恐らくプログラムの歴史的にgotoが難解なプログラムを生み出したという経緯がある為、むやみに使うなということになっているのだと思います。
gotoは使い方次第で酷いプログラムにも良いプログラムにもなりますが、
使い方をしっかり理解しないで使うと前者になりがちです。
また、gotoを書かなければ実行できない処理はありません。
ですから、初心者のうちは使わないようにと教えるのが一般的になっているものと思います。
# 今月号のinterfaceにプログラムの歴史的な事が書いてありました。
http://interface.cqpub.co.jp/
gotoが何故悪いかという例も色々書いてあって面白かったので、よければどうぞ。
178ポイント を手に入れた。
|
|
|
|
|
Name: べの ..ぴよぴよ(808ポイント)
Date: 2010/09/14(火) 20:37
No:61748
| 解決!
|
Title: Re:scanf文について
|
|
色々とありがとうございます。
まだこんなレベルではありますが、今後も行き詰ることがあればお世話になるかと思います。
宜しくお願い致します。
44ポイント を手に入れた。
|
|
|
|
|
Name: たかぎ [URL] ..ハッカー(227,868ポイント)
Date: 2010/09/14(火) 20:46
No:61750
|
|
Title: Re:scanf文について
|
|
> gotoは使い方次第で酷いプログラムにも良いプログラムにもなりますが、
> 使い方をしっかり理解しないで使うと前者になりがちです。
そういうことです。
なお、gotoを使わないままでいると、いつまでたっても使いこなせるようにはなりません。
使える状況では(失敗覚悟ででも)使ってみることをお勧めします。
どんな言語機能も、使いこなせなければ酷いプログラムの量産につながるだけですので、実際に使ってみて、失敗しながら身につける方がよいのです。
> また、gotoを書かなければ実行できない処理はありません。
その代わり、制御の流れを(本来必要ないはずの)フラグ等の変数に依存することになってしまいます。
また、その論法でいけば、ifとgotoを使えばすべての制御構造は記述できるので、for文もwhile文もdo文もswitch文も不要になります。
現実にはそんなことはないので、やはり適材適所なのでしょう(多くの場合、技術的なことではなく、人員の力量に左右されることが多いのが困りものですが...)。
ちなみに、gotoの濫用で酷くなったプログラムというのは、昔のBASICなど、関数内のローカルなgotoではなく、グローバルなgotoによって生み出されました。
構造化プログラミングでは、(ローカルな)gotoを使ったコーディングではなく、(グローバルな)goto文という言語仕様の導入が禁止なのだと思います。
362ポイント を手に入れた。
|
|
|
|
|
Name: box ..ハッカー(157,230ポイント)
Date: 2010/09/14(火) 20:46
No:61752
|
|
Title: Re:scanf文について
|
|
どこからも指摘がなかったようですが、
scanf「文」ではなくてscanf「関数」です。
20ポイント を落としてしまった。
|
|
|
|
Name: shiro4ao ..中級者(9,875ポイント)
Date: 2010/09/14(火) 03:43
No:61689
|
|
Title: 自前の通信プロトコルの実装
|
|
バイト数,データ
となっている、データがTCPソケットでsend()されます。
例)10,1234567890
7,abcdefg
このデータの部分を途中で切れることなく送った通りに受け取りたいのです。
例)
10,1234567890
が送られてきたら
1234567890
とバッファに入って欲しい
123
で一旦途切れて、
4567890
と来てほしくない
以下のように書いたのですが、実行すると10バイト送った場合、
後ろにゴミと思われるデータがくっついてバッファに書き込まれました。
何か解決方法はありますか?
それとも根本的におかしいのでしょうか?
====================ここから=============================================
int recvex (SOCKET sock, char * buf, int len,int flags )
{
int ret,ret2=0,i;
BOOL Flag=TRUE; // データ長を示す部分が有るか無いか
char *size,tmp1[1024],*tmp2;
size = (char *)malloc(sizeof(char));
tmp2 = (char *)malloc(sizeof(char));
memset(buf,'\0',sizeof(buf));
memset(tmp2,'\0',sizeof(tmp2));
memset(tmp1,'\0',sizeof(tmp1));
//データ長と同じサイズになるまでrecvする
while(ret2==atoi(size)){
if(Flag){
//ここはデータ長の部分が含まれている時の処理
ret= recv(s,tmp1,100, flags);
CmdTok(tmp1,",",2,&tmp2);
strcat(buf,tmp2);
ret2=strlen(tmp1)+ret2;
//データ長の取得
DataTok(tmp1,",",1,&size);
Flag=FALSE;
}else{
//ここはデータ長移行の部分の処理
memset(tmp2,'\0',sizeof(tmp2));
ret= recv(s,tmp2,100, flags);
strcat(buf,tmp2);
ret2=ret+ret2;
}
}
return ret2;
}
//bufから、第三引数が1なら","以前の部分を、2なら","移行の部分を取り出す
int DataTok(char *buf ,char *div,int n ,char **ret){
int i;
*ret = strtok(buf,div);
for(i=0;i<n-1;i++) *ret = strtok(NULL,div);
return 0;
}
====================ここまで=================================================
294ポイント を手に入れた。
|
|
|
|
Name: toyo ..熟練のプログラマー(61,015ポイント)
Date: 2010/09/14(火) 07:20
No:61695
|
|
Title: Re:自前の通信プロトコルの実装
|
|
mallocとstrtokの使い方が良くわかっていないように思います
tmp2 = (char *)malloc(sizeof(char));
ですが
sizeof(char)は1ですので
tmp2 = (char *)malloc(1);
となりtmp2には1バイトの領域しか確保されません
char tmp2[1];
と同じ意味になります
strtokの返り値を受けるもののようなのでその場合mallocする必要はないです
freeするのも忘れています
もちろんこのままfreeしてもポインタの値が変わっているのでエラーになってしまいますが
memset(tmp2,'\0',sizeof(tmp2));
もいらないというか問題を悪化させています
sizeof(tmp2)はポインタのサイズなのでおそらく4になります(64ビット用にコンパイルする場合は8)
1バイトの領域しかないのに4バイト0にするので問題です
結論として
size = (char *)malloc(sizeof(char));
tmp2 = (char *)malloc(sizeof(char));
memset(tmp2,'\0',sizeof(tmp2));
は必要ないです
memset(buf,'\0',sizeof(buf));
も考えた方がいいでしょう
299ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..熟練のプログラマー(61,163ポイント)
Date: 2010/09/14(火) 07:41
No:61696
|
|
Title: Re:自前の通信プロトコルの実装
|
|
次にstrtokですがこれは引数に渡した文字列を破壊していきます
文字列を後でまた使いたいときには別にコピーを保存しておかないといけません
CmdTok(tmp1,",",2,&tmp2);
の時点でtmp1は破壊されているのでこの後
strlen(tmp1)
しても期待した値は得られません
ret2==atoi(size)
の部分もsizeを初期化してないのでよくないです
質問のゴミがつく問題ですがこれは
memset(tmp2,'\0',sizeof(tmp2));
で最初の4バイトしか0にしてないのが原因でしょう
memset(tmp2,'\0',100);
にすればとりあえずゴミはなくせると思います
148ポイント を手に入れた。
|
|
|
|
|
Name: YuO ..熟練のプログラマー(47,041ポイント)
Date: 2010/09/14(火) 10:46
No:61698
|
|
Title: Re:自前の通信プロトコルの実装
|
|
> データがTCPソケットでsend()されます。
> このデータの部分を途中で切れることなく送った通りに受け取りたいのです。
前提条件がおかしいです。
TCPは「データ送信境界が保持されない」ものなので,
「途中で切れることなく送った通りに受け取りたい」を満たすプロトコルではありません。
「途中で切れることなく送った通りに受け取りたい」が重要であればUDPなどのプロトコルを使うべきですし,
TCPの各機能 (再送とか欠損のチェックなど) が重要であれば,送信と受信が一対一でないことを前提としてプログラムを組むべきです。
今回の場合,先頭にサイズが含まれるのですから,それを使ってサイズを決定するべきでしょう。
SITE: Winsock Programmer's FAQ: Articles: The Lame List
http://www.kt.rim.or.jp/~ksk/wskfaq-ja/articles/lame-list.html#item20
2倍のポイントを手に入れた! 122ポイント を手に入れた。
|
|
|
|
|
Name: shiro4ao ..中級者(9,973ポイント)
Date: 2010/09/14(火) 20:05
No:61739
| 解決!
|
Title: Re:自前の通信プロトコルの実装
|
|
>toyoさん
1バイトしか割り当てられていなかったのですね。
仕組みがよくわかりました。
>YuOさん
ご紹介のサイトで、自分がいろいろ誤解をしていたことがわかりました。
どうしても上手くいかなかったのでプロトコルを変更して
実装したら、希望どおりの動作になりました。
ありがとうございました。
98ポイント を手に入れた。
|
|
|
|
Name: ぷりん ..ぴよぴよ(48ポイント)
Date: 2010/09/14(火) 18:04
No:61707
|
|
Title: C言語ってなにができるんですか?
|
|
なんか本とか読むとOS作ったりも出来るし何でも出来るみたいなこと書いてますが・・・
C言語の関数だけで到底作れるものではないと思うのですが?
C言語の関数だけで作るとしたらどういうものが作れるのですか?
48ポイント を手に入れた。
|
|
|
|
Name: たかぎ [URL] ..ハッカー(227,362ポイント)
Date: 2010/09/14(火) 18:10
No:61708
|
|
Title: Re:C言語ってなにができるんですか?
|
|
> C言語の関数だけで作るとしたらどういうものが作れるのですか?
Cの文法の範疇で表現できない(物理的にアクセスできないものを含む)ハードウェアの制御を除く、すべてのものが作れます。
ただし、それはあくまでも技術的な話であって、予算や開発期間など、他の要因によってできないことはあり得ます。
57ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) [URL] ..ウィザード(1,276,150ポイント)
Date: 2010/09/14(火) 19:33
No:61728
|
|
Title: Re:C言語ってなにができるんですか?
|
|
多分今はprintfやscanfのような標準関数しかまだご覧になったことが無いのではないでしょうか。
恐らく今C言語を書き始める時に
#include <stdio.h>
と書いていると思います。
これはstdio.hというライブラリをインクルードして、出来る事を増やしています。
C言語って実は何もライブラリを使わない状態だとすごくちょっとの事しか出来ません。
コンソール画面に文字を表示することも出来ません。
しかしprintfという関数を使うためにstdio.hというライブラリをインクルードすることで、出来る事が増え、画面に文字を表示することが出来るようになります。
そんな風にライブラリをドンドンインクルードしていくことで出来る事がドンドン増えていきます。
例えば、コンソールプログラムをどんなに勉強してもWordみたいなソフトは作れる気がしないと思うかもしれません、
しかしwindows.hをインクルードして、WINAPIを使うようになれば、次第に作れそうな気がしてくるかもしれません。
C言語を使えば何でも作れますが、難しい事をするなら専門的な知識が必要です。
逆に専門的な知識があれば、一般的なソフトウェアならなんだって作れます。
ぷりんさんの今のC言語のスキルを補足してもらえたらより的確なアドバイスがもらえるかもしれません。
何か目標を持ってこれを作りたいというものがあれば、それについて質問されてはいかがでしょうか。
426ポイント を手に入れた。
|
|
|
|
|
Name: たかぎ [URL] ..ハッカー(227,542ポイント)
Date: 2010/09/14(火) 19:49
No:61731
|
|
Title: Re:C言語ってなにができるんですか?
|
|
ちなみに、純粋な標準Cの機能だけを使ったのでは、できないことはたくさんあります。
メモリ上の任意のアドレスにアクセスすることさえ、できるとは限りません。
逆に、処理系の独自拡張を使えば、CだけでOSができてしまう可能性もあります。
OSを作る上で最初の関門となるのは、スタックポインタをどうやって設定するかであり、割り込みの禁止と許可をどうやって制御するかです。
これらを何とかする独自拡張機能(場合によってはインラインアセンブラ)が備わっていれば、かなりのところまで進みます。
180ポイント を手に入れた。
|
|
|
|
Name: 42 ..ぴよぴよ(142ポイント)
Date: 2010/09/12(日) 12:23
No:61591
|
|
Title: コンパイルのエラーで・・・
|
|
こんにちわ、はじめまして。
ここで紹介しているC言語でゲームを作れる講座を見て、私も作ろうと思い、DXライブラリをダウンロードし、環境設定を本家で書かれているように設定した後、ビルドをしたら、mmreg.hをユニコードにしないといけないというエラーが起きたので上書き保存してサイドビルドしたら”TRACKER : error TRK0002: ”というエラーが出てしまったので検索してみたのですが、解決策が見つからず、そこで行き詰ってしまいました。
今回動かした環境は
OS:Windows7 professional 64ビット
VC:Visual C++ 2010
です。
一応、ここの掲示板でも検索してみたのですが、見つからなかったので質問します。
既存だったらすみません・・・
142ポイント を手に入れた。
|
|
|
|
Name: ISLe ..上級者(21,772ポイント)
Date: 2010/09/13(月) 00:15
No:61632
|
|
Title: Re:コンパイルのエラーで・・・
|
|
Visual C++のエディションは何でしょうか?
TRK0002というエラーは64ビットアプリをビルドしようとしたときに出るエラーらしいのでExpressではないと思いますけど。
x64(amd64)構成でビルドしているならx86の構成でビルドしてみてください。
56ポイント を手に入れた。
|
|
|
|
|
Name: 42 ..ぴよぴよ(49ポイント)
Date: 2010/09/13(月) 19:35
No:61660
|
|
Title: Re:コンパイルのエラーで・・・
|
|
返信ありがとうございます
Visual C++のエディションはExpressです。
32bit用と64bit用でプログラムファイルを分けているらしく、Expressは32bit用のをダウンロードしているようです。
それで構成ですが・・・メニュータブの中にある[プロジェクト]の[プロパティ]の[構成プロパティ]のVC++ディレクトリを変更すればいいんでしょうか?
それともビルドの構成マネージャーでしょうか・・・?
49ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(22,021ポイント)
Date: 2010/09/13(月) 21:55
No:61675
|
|
Title: Re:コンパイルのエラーで・・・
|
|
Expressは64ビットには対応していないので単体でTRK0002エラーが出ることはないはずなのです。
なので構成のことは忘れてください。
どこかで間違って64ビット版のツールを呼び出しているところがあるのではないかと思います。
DirectX SDKやWindows SDKには64ビット版の開発ツールが含まれているので、パスの設定が64ビット版のフォルダになっているかもしれません。
環境設定を見直してみてください。
見直しても分からないときは変更した内容を教えてください。
172ポイント を手に入れた。
|
|
|
|
|
Name: 42 ..ぴよぴよ(204ポイント)
Date: 2010/09/13(月) 23:41
No:61681
|
|
Title: Re:コンパイルのエラーで・・・
|
|
返信ありがとうございます。
今プログラムファイルの中を見てきたところWindowsSDKが64ビット版でダウンロードされていました。
WindowsSDKの32ビット版を入れなおせたら入れてみようと思います
9/14 0:10
WindowsSDKをアンインストールして再起動後新しくインストールしようとしたらインストールできない状態になりました・・・いろいろ調べて再インストールするようにしてきます・・・ 
62ポイント を手に入れた。
|
|
|
|
|
Name: 42 ..ぴよぴよ(103ポイント)
Date: 2010/09/14(火) 18:40
No:61714
| 解決!
|
Title: Re:コンパイルのエラーで・・・
|
|
コンパイルエラーなおりました
Webダウンロード版で再インストールして正常にデバッグするようになりました。
前回ダウンロードしたSDKを見直した所、一つ前のバージョンだった見たいですが、GRMSDK_EN_DVD.iso でインストールしたので32bitのはずでしたが・・・あとこれを再インストールできなかったのもまだよくわかってないです・・・ 
101ポイント を落としてしまった。
|
|
|
|
Name: 鏡 ..ぴよぴよ(517ポイント)
Date: 2010/09/14(火) 00:36
No:61683
|
|
Title: C言語 ポインタ
|
|
こんにちは。
ゲームを作ることを目標にして、C言語の勉強をしています。
そこで、確認と質問したいことがあるので質問させていただきます。
まず、確認でC言語の問題集で「文字列の長さを調べる関数 lenght(char str[]) をポインタで表記しろ」
という問題がありました。
そして、自分で作ったコードはこちらです。見やすく作ってないので見難いかもしれません。
#include < stdio.h>
int lenght(char *str);
int main(void)
{
char str[100];
int ans;
printf("文字列を入力してください。\n");
scanf("%s" , str);
ans = lenght(str);
printf("文字列の長さは%dです\n" , ans);
return 0;
}
int lenght(char *str)
{
int num , i;
i=0;
for(num=0 ; str[num]!='\0'; num++)
i++;
return i;
}
これでデバッグしたところ、正常に出来ました。(環境VisualC++2008)
このコードでポインタを使って表記できてますか?
確かに、関数を宣言(?)するところでは、「*」を使ってますが、lenght(char *str[])関数の内容で
ポインタが使われてない(?)ように見えます。この書き方で合ってるでしょうか?
もう一つの質問は、
for(num=0 ; str[num]!='\0'; num++)
の str[num] の部分で、何故 strの前に「*」を付けなくて良いのでしょうか?
確か、 str だけでは、strのアドレスを表すと書いてありました。
str に格納されているものを指すには strの前に「*」を付けると書いてあります。
ということは、 *str[num]!=・・・ と表記するべきではないでしょうか?
しかし、 * を付けるエラーになってしまいます。どうしてでしょうか?
まだまだC言語は初心者で「付けないのは当たり前だろ!」とか思うかもしれませんがよろしくお願いします。
また、質問の意味が分からなかったらすみません。
468ポイント を手に入れた。
|
|
|
|
Name: うしお ..入門者(2,749ポイント)
Date: 2010/09/14(火) 03:46
No:61690
|
|
Title: Re:C言語 ポインタ
|
|
まず
lenghtではなくlengthではないでしょうか?
質問1
正しいと思います
また、Numはなくても良いかと思います
たとえば
int length(const char *str){
int i = 0;
for(i;str[i]!='\0';++i){
}
return i;
}
質問2
ポインタと配列には密接な関係があります
char Array[5];
ならば、
char *p = Array;
とこの表記だとこのポインタには配列の先頭アドレスが入ります
そして、ポインタは配列と扱うことも出来ます
char a = p[3];
とアクセスも可能です(ここが質問の肝ですね!
また、
char b = *p;
も勿論可能で、
char c = *(p+3);
という取り出し方もあります(こちらは普通はあまりしないかもしれません)
この方法は「ポインタ演算」という方法です
調べてみると理解が深まるかと思います
以上のことが理解できれば
「付けないのは当たり前だろ!」
と安心して叫ぶことができるでしょう
316ポイント を手に入れた。
|
|
|
|
|
Name: fatens ..上級者(19,159ポイント)
Date: 2010/09/14(火) 09:37
No:61697
|
|
Title: Re:C言語 ポインタ
|
|
>このコードでポインタを使って表記できてますか?
「文字列の長さを調べる関数 lenght(char str[]) をポインタで表記しろ」
この指示が何を求めているのか正確には分かりませんが……
str[num]のような配列の形を使わずに書き直す、ということではないでしょうか。
だとすれば、できていませんね。
>確かに、関数を宣言(?)するところでは、「*」を使ってますが、lenght(char *str[])関数の内容で
>ポインタが使われてない(?)ように見えます。この書き方で合ってるでしょうか?
ご自身も疑問に思われているようですので、上で書いたように書き直してみてはどうでしょう。
175ポイント を手に入れた。
|
|
|
|
|
Name: 鏡 ..ぴよぴよ(810ポイント)
Date: 2010/09/14(火) 17:39
No:61705
|
|
Title: Re:C言語 ポインタ
|
|
皆様、丁寧なご回答ありがとうございます。
この問題は、C言語のポインタを自分でより扱える・理解するようにして作られた問題です。
なので、何故ポインタを使って表記するのか理由はありません。
一度 *str[num] と書き直してみたところ、エラーが出ました。
添付していただいた配列とポインタのサイトを参考にして、C言語のポインタの理解をより深めようと思います。
詳しい解説・指摘ありがとうございます。
何となく・・・分かったような気がします。
もう少し色々と勉強してみてより理解を深めようと思います。
これで、 叫べそう(?)です!
皆様、ありがとうございました!
これからも利用させていただこうと思います。
293ポイント を手に入れた。
|
|
|
|
Name: Ultimate [URL] ..中級者(14,914ポイント)
Date: 2010/09/12(日) 11:18
No:61583
|
|
Title: 一定時間ごとに全方向ショット
|
|
現在、弾幕を作成していて、一定時間ごとに敵が円形にショットを打つようにしようと思っています。
その作り方については下のようにすることでできますか?
もっと良い方法があったら教えてください。
1.弾の構造体を作る。
typedef struct{
int x[100]; //X座標 弾の数である100個を作成
int y[100]; //Y座標 弾の数である100個を作成
int nagasa[5]; //X座標、Y座標の基準になる長さ 20個ずつに分けるので5個作成
double sinsin[100]; //サイン値 弾の数である100個を作成
double coscos[100]; //コサイン値 20個ずつに分けるので5個作成
double r[100]; //ラジアン値 20個ずつに分けるので5個作成
int flag[5]; //フラグ 20個ずつに分けるので5個作成
int count; //カウント
}ch_t;
ch_t tmain1;
2.0〜19,20〜39,40〜59,60〜79,80〜99のように20個ずつサイン、コサインを設定。その他0に初期化。
3.1ループごとにカウンターを1ずつ増やし、まず1組目発射、100カウントごとに次へと発射し、それぞれ500カウントごとに消し、初期化
こんな感じでいけるかなと思うのですが、もっと良い方法はありますか?
262ポイント を手に入れた。
|
|
|
|
Name: Ultimate ..上級者(15,253ポイント)
Date: 2010/09/12(日) 21:10
No:61625
|
|
Title: Re:一定時間ごとに全方向ショット
|
|
すみませんが、そのページなどは関数を作りやっているようです。
メインの関数の中に直接書く方法を教えてください。
すでに作ってある変数は以下の通りです。
typedef struct{
int x[100]; //X座標 弾の数である100個を作成
int y[100]; //Y座標 弾の数である100個を作成
int nagasa[5]; //X座標、Y座標の基準になる長さ 20個ずつに分けるので5個作成
double sinsin[100]; //サイン値 弾の数である100個を作成
double coscos[100]; //コサイン値 20個ずつに分けるので5個作成
double r[100]; //ラジアン値 20個ずつに分けるので5個作成
int flag[5]; //フラグ 20個ずつに分けるので5個作成
int count; //カウント
}ch_t;
ch_t tmain1;
ソースでなくて、最初の質問文のように言葉で手順を書いていただけるだけで十分です。
278ポイント を手に入れた。
|
|
|
|
|
Name: Ultimate ..上級者(15,355ポイント)
Date: 2010/09/12(日) 21:47
No:61627
|
|
Title: Re:一定時間ごとに全方向ショット
|
|
読んで、弾を20個ずつに分け、それぞれを18度ずつ設定しました。
ラジアンを求める部分のソース
if(i>0){
tmain1.r[i]=2.0*PI/(19.0/(double)i);//弾それぞれのラジアンを求める。(最初の20個)
}
else tmain1.r[i]=0;
その後のことがわからないです。
102ポイント を手に入れた。
|
|
|
|
Name: dic ..比類無きプログラマー(96,135ポイント)
Date: 2010/09/13(月) 19:17
No:61659
|
|
Title: 開発スタイルについて
|
|
新規にSLGを作ろうと考えています
そこで、タスクシステムを使うか、自作のライブラリを作るか迷っています
自分なりにそれぞれの長所、短所を挙げてみましたが、なかなかどちらを採用するか
迷っています
規模は私には中くらいになると思っています
■タスクシステム
長所:一般に知られているので、指摘を受けやすい
短所:応用が私には難しい
■自作のライブラリ
長所:いろいろいじりやすい
短所:バグなどが入ると見つけるのが困難、設計しだいで
管理が複雑になる
上のような感じになります
どちらがお勧めか意見を聞きたいです
193ポイント を落としてしまった。
|
|
|
|
Name: Tororo ..中級者(10,395ポイント)
Date: 2010/09/13(月) 19:41
No:61661
|
|
Title: Re:開発スタイルについて
|
|
タスクシステムを内蔵した、自作ライブラリを作るのはどうですか?
今、自分はそうしていますけど。。
26ポイント を手に入れた。
|
|
|
|
|
Name: dic ..比類無きプログラマー(96,204ポイント)
Date: 2010/09/14(火) 13:58
No:61700
| 解決!
|
Title: Re:開発スタイルについて
|
|
>Tororoさん
たしかに色々タスクシステムオンリーでなく
機能を追加する形が私には合いそうです
意見ありがとうございました

69ポイント を手に入れた。
|
|
|
|
Name: mol ..ぴよぴよ(122ポイント)
Date: 2010/09/11(土) 14:08
No:61497
|
|
Title: 文字列の代入されている場所について
|
|
こんにちは。
文字列について、「あいうえお」等の全角文字を配列に代入したい時、この場合5文字なので
char a[11];のように少なくとも11バイトのメモリを確保しなくてはならないのですよね?
そうすると、例えば「あ」はa[0]とa[1]に代入されることになりますか?
そうなった時、後で単発に「あ」を取り出したいとき、どのように処理をすればよいのでしょうか。
(例えば、3つ目の文字が「う」であるかどうかの判定は、「う」がa[4]とa[5]に代入されているため、a[4]=='う';とするのですか?)
122ポイント を手に入れた。
|
|
|
|
Name: へろり ..プログラマー(37,953ポイント)
Date: 2010/09/11(土) 15:52
No:61500
|
|
Title: Re:文字列の代入されている場所について
|
|
この手の話は、文字コードに依存しますので、勝手にShift-JISを前提とします。
ついでに、char 型が1バイトであることを前提とします。
>文字列について、「あいうえお」等の全角文字を配列に代入したい時、この場合5文字なので
>char a[11];のように少なくとも11バイトのメモリを確保しなくてはならないのですよね?
ですね。
>そうすると、例えば「あ」はa[0]とa[1]に代入されることになりますか?
そうなります。
>そうなった時、後で単発に「あ」を取り出したいとき、どのように処理をすればよいのでしょうか。
2バイト長のサイズを持つ型 type を使い
*(type*)&a[0]; という風にすれば可能です。
>(例えば、3つ目の文字が「う」であるかどうかの判定は、「う」がa[4]とa[5]に代入されているため、a[4]=='う';とするのですか?)
if(a[4] == "う"[0] && a[5] == "う"[1]) とするか
if(*(type*)&a[4] == *(type*)"う") とするか
if(!strncmp(&a[4], "う", 2)) とでもします。
type は環境に合わせて読み替えてください。
417ポイント を手に入れた。
|
|
|
|
|
Name: mol ..ぴよぴよ(286ポイント)
Date: 2010/09/12(日) 00:54
No:61538
|
|
Title: Re:文字列の代入されている場所について
|
|
たかぎさん>>なるほど、考えていませんでした。ええと、文字コードというのはパソコンごとに決まっているものなのですか?逆にプログラムによってこのプログラムはShift-JISを使用すると宣言できるものなのでしょうか?
へろりさん>>丁寧にありがとうございます。比較の例、非常にためになりました!
"う"[0]で「う」の前半の文字コードを示しているということでよろしいですか?
しかし、*(type*)&a[0]; とはどういった意味(文法?)でしょうか?
シエルさん>>自分の知識レベルを完全に超えていました。折角なのに申し訳ないです。
164ポイント を手に入れた。
|
|
|
|
|
Name: へろり ..プログラマー(38,314ポイント)
Date: 2010/09/12(日) 06:57
No:61551
|
|
Title: Re:文字列の代入されている場所について
|
|
>"う"[0]で「う」の前半の文字コードを示しているということでよろしいですか?
言わんとするところは解りますので、その通りです。 と言いたいところですが。
言い切ってしまうと識者諸氏からの突っ込みを受けますので、重隅を承知で訂正させていただきます。
文字コードとはあくまでもShift-JISや、EUC-JP、Unicode等の文字を表現するビットパターンの体系の事ですので、正確には、"う"[0]は"う"の上位バイト。 ということになります。
>しかし、*(type*)&a[0]; とはどういった意味(文法?)でしょうか?
a 変数 a の
a[0] [0]番目の要素の
&a[0] ポインタを
(type*)&a[0] (type*)型でキャストして
*(type*)&a[0] で、アドレスを解決。
です。
2倍のポイントを手に入れた! 388ポイント を手に入れた。
|
|
|
|
|
Name: mol ..ぴよぴよ(259ポイント)
Date: 2010/09/12(日) 11:59
No:61587
|
|
Title: Re:文字列の代入されている場所について
|
|
シエルさん>>半分理解しました。しかしまだ一つ疑問があります。
27ポイント を落としてしまった。
|
|
|
|
|
Name: mol ..ぴよぴよ(425ポイント)
Date: 2010/09/12(日) 12:09
No:61589
|
|
Title: Re:文字列の代入されている場所について
|
|
申し訳ないです。上記のはミスです。
すいません、当初の質問からズレてしまいますが、(それ以前の知識がありませんでした。)
例えばこの場合、(文字コードはSift-JIS、char型が一バイトととして、type型が二バイトとします)
*(type*)&a[0]の意味は、前半は(一バイト目)もともとのa[0]のポインタを示していて、後半は(二バイト目)a[1]のポインタを指しているのですか?
つまりキャストする前よりキャスト後の方がメモリが大きいとき、自動的に読み込まれるのはメモリの次のアドレスに入っている要素なのでしょうか?
166ポイント を手に入れた。
|
|
|
|
|
Name: へろり ..プログラマー(38,397ポイント)
Date: 2010/09/12(日) 13:10
No:61595
|
|
Title: Re:文字列の代入されている場所について
|
|
>つまりキャストする前よりキャスト後の方がメモリが大きいとき、自動的に読み込まれるのはメモリの次のアドレスに入っている要素なのでしょうか?
言いたいことが今ひとつ分かりません。
ポインタというのは要するに、ただ指し示す者。 それだけです。 実際のデータが格納されている場所(アドレス)を保持します。 それだけです。
例えば次のようなメモリマップがあったとします。
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
┏━━━━━━━━━━━━━━━━━━━━━━━━
0010┃00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0020┃00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
</pre>
そこで
char a[5] = {0x01, 0x02, 0x03, 0x04, 0x05};
とします。
この時、変数 aの先頭要素(a[0])へのポインタ(&a[0])が 0015 の値を持つ時、
メモリには次のように書き込まれます。
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
┏━━━━━━━━━━━━━━━━━━━━━━━━
0010┃00 00 00 00 00 01 02 03 04 05 00 00 00 00 00 00
0020┃00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a[0] はアドレス 0015 に書き込まれており、その値は 0x01 です。
a[1] はアドレス 0016 に書き込まれており、その値は 0x02 です。
a[2] はアドレス 0017 に書き込まれており、その値は 0x03 です。
ここで、2バイト長の幅を持つ型 type を使い、
type* baa = (type*)&a[0]; とポインタ同士をキャストします。
ポインタは指し示す者で、その値はアドレスですから、この時の変数 baa の値は 0015 となりますね。
0015 の場所を指し示しています。
では、*baa と間接演算子を使いアドレスを解決した時の値は何になるかと言うと、変数 baa の型は type で、型 type は2バイト長な訳ですから、0x0102 となりますね。 ただそれだけの話です。
baa と &a[0] は同じ値で、baa と (type*)&a[0] は同じ意味で、*baa と、*(type*)&a[0] もやっぱり、全く同じ意味になります。
221ポイント を手に入れた。
|
|
|
|
|
Name: mol ..ぴよぴよ(704ポイント)
Date: 2010/09/12(日) 15:05
No:61601
|
|
Title: Re:文字列の代入されている場所について
|
|
へろりさん>>丁寧に本当にありがとうございます。
> ここで、2バイト長の幅を持つ型 type を使い、
> type* baa = (type*)&a[0]; とポインタ同士をキャストします。
> ポインタは指し示す者で、その値はアドレスですから、この時の変数 baa の値は 0015 となりますね。
> 0015 の場所を指し示しています。
> baa と &a[0] は同じ値で、baa と (type*)&a[0] は同じ意味で、*baa と、*(type*)&a[0] もやっぱり、全く同じ意味になります。
ここが疑問なのですが、(&a[0]が 0015 の値を持っていて)キャストした後の(type*)&a[0]もアドレスが変わらないのですか?つまり妙な書き方ですが(&a[0]==(type*)&a[0])=1ですか?(ではキャストする効果はどこに現れているのでしょう?)
そうすると、
> では、*baa と間接演算子を使いアドレスを解決した時の値は何になるかと言うと、変数 baa の型は type で、型 type は2バイト長な訳ですから、0x0102 となりますね。
とありますが、 上記の話でbaa=(type*)&a[0]=&a[0]なので、間接参照すると*baa==*(type*)&a[0]=*(&a[0])となってしまいそうですが・・・(なるわけがない事は分かっています。)
(もしかして、「(type*)&a[0]」というのは「二バイト超の値のポインタの先頭部分」という意味になるのですか?)
279ポイント を手に入れた。
|
|
|
|
|
Name: たかぎ [URL] ..ハッカー(226,970ポイント)
Date: 2010/09/12(日) 18:54
No:61614
|
|
Title: Re:文字列の代入されている場所について
|
|
> 文字コードというのはパソコンごとに決まっているものなのですか?
いいえ。
> 逆にプログラムによってこのプログラムはShift-JISを使用すると宣言できるものなのでしょうか?
それも厳密にいうと違います。
結局のところ、処理系や利用状況が不明のままでは、想像に次ぐ想像で回答するしかなく、まともな話にはなりません。
もっとはっきりいえば、質問する前に利用規約をちゃんと読み、それを守りましょう、ということです。
116ポイント を手に入れた。
|
|
|
|
|
Name: たかぎ [URL] ..ハッカー(227,305ポイント)
Date: 2010/09/12(日) 19:04
No:61615
|
|
Title: Re:文字列の代入されている場所について
|
|
一応、処理系不明のままで回答すれば...
> 文字列について、「あいうえお」等の全角文字を配列に代入したい時、この場合5文字なので
> char a[11];のように少なくとも11バイトのメモリを確保しなくてはならないのですよね?
特殊な状況ではそうなりますが、一般的には違います。
char a[MB_CUR_MAX * 5 + 1];
とする必要があります。
ただし、旧規格にしか対応していない処理系であれば、MB_CUR_MAXの代わりにMB_LEN_MAXを使うか、mallocで動的に配列を割り付けるなどの方法をとらなければなりません。
> そうすると、例えば「あ」はa[0]とa[1]に代入されることになりますか?
特殊な状況ではそうなりますが、一般的には違います。
最大で、a[0] 〜 a[MB_CUR_MAX - 1] の範囲に格納されることになります。
もちろん、これより短い可能性はあります。
> そうなった時、後で単発に「あ」を取り出したいとき、どのように処理をすればよいのでしょうか。
適切にロケールを設定した上で...
mbstate_t state = {0};
size_t length = mbrlen(a, MB_CUR_MAX, &state);
char b[MB_CUR_MAX];
memcpy(b, a, length);
とすれば、b[0]〜b[length-1]の範囲に「あ」に相当する部分の値が取り出せます。

335ポイント を手に入れた。
|
|
|
|
|
Name: mol ..ぴよぴよ(836ポイント)
Date: 2010/09/14(火) 13:06
No:61699
|
|
Title: Re:文字列の代入されている場所について
|
|
たかぎさん>>申し訳ないです。この関係の話が開発環境に依存するとは知らなかったので…
(ちなみに一応開発環境はwindowsxp,コンパイラがborlandC++で開発環境がBCCDeveloperでした。)
MB_CUR_MAXを用いる方法は全く知りませんでした。
丁寧にありがとうございました。
132ポイント を手に入れた。
|
|
|
|
Name: blue ..初心者(6,404ポイント)
Date: 2010/09/12(日) 16:35
No:61605
|
|
Title: ポインタを使った文字列交換
|
|
重要課題 12..3
2つのchar型配列x[],y[]に格納された文字列を入れ替えるプログラムを作 成せよ.ただし入替え処理には,関数swap_string(char [],char [])を作 成して用いること.下記の例では,2つの文字列xとyをキーボードから入力し,入 れ替えた後に表示している.
% ./stringSwap
文字列x (20字まで)? Ritsumeikan
文字列y (20字まで)? BKC
関数swap_string()を呼び出しました
入替後の x: "BKC"
入替後の y: "Ritsumeikan"
%
発展課題 14..2
重要課題12.3で作成した関数をポインタを使って実現せ よ。すなわち、2つのchar型配列x[],y[]に格納された文字列を入れ替える プログラムを,関数swap_stringWithPointer(char *, char *)を用いて実 装せよ.下記の例では,2つの文字列xとyをキーボードから入力し,入れ替えた後 に表示している.
% ./stringSwap
文字列x (20字まで)? Ritsumeikan
文字列y (20字まで)? BKC
入替後の x: "BKC"
入替後の y: "Ritsumeikan"
%
学校の前期の課題を復習していてわからないことがあったので質問します。
自分で考えてソースを書いてコンパイルして実行するとなぜか入力できなくなっています。
どう直せばよいでしょうか?
自分が書いたソース↓
#include <stdio.h>
# define BUFFER_SIZE (20)
int get_int(void)
{
char buf[BUFFER_SIZE];
fgets(buf, BUFFER_SIZE, stdin);
return atoi(buf);
}
void swap_string(char *,char *);
int main(void){
int i,j;
char arrayX[BUFFER_SIZE],arrayY[BUFFER_SIZE];
char *p,*q;
//pの初期値を配列の先頭に設定
p = arrayX;
q = arrayY;
//入力
printf("文字列x(20字まで) :");
for(i=0; i!='\0' ; i++){
*p = get_int();
p++;
}
printf("\n");
printf("文字列y(20字まで) :");
for(j=0; j!='\0' ; j++){
*q = get_int();
q++;
}
printf("\n");
swap_string(p,q);
printf("入り替え後のx :");
for(i=0 ; i !='\0'; i++){
printf("%c",*p);
}
printf("\n");
printf("入り替え後のy :");
for(j=0; j!= '\0'; j++){
printf("%c",*q);
}
printf("\n");
return 0;
}
void swap_string(char *a,char *b){
int i,temp[BUFFER_SIZE];
for(i=0 ; i< BUFFER_SIZE ; i++){
temp[i] = *a;
*a = *b;
*b = *a;
a++;
b++;
}
}
z
1,115ポイント を手に入れた。
|
|
|
|
Name: バグ ..ハッカー(214,032ポイント)
Date: 2010/09/12(日) 16:41
No:61606
|
|
Title: Re:ポインタを使った文字列交換
|
|
前にも書きましたが、処理の途中にprintf関数を置いて、自分の意図する動きになっているかを確認してみてください。
それでも分からなければ、また質問しにきてください。
自分で修正できる力を身に付けなければ、復習する意味が全くありませんよ。
113ポイント を手に入れた。
|
|
|
|
|
Name: blue ..初心者(6,598ポイント)
Date: 2010/09/13(月) 12:06
No:61646
| 解決!
|
Title: Re:ポインタを使った文字列交換
|
|
なんとかこの問題を解くことできました。
変更したのは
25〜35行目の
for(i=0; i!='\0' ; i++){
*p = get_int();
p++;
}
をfgets(*p,BUFFER_SIZE,stdin);
にかえたことと
38〜46行目の
for(i=0 ; i !='\0'; i++){
printf("%c",*p);
}
をwhile(*p){
printf("%c",*p);
}
にかえたことと
char *k;
k=array;
にして
55〜62行目の
for文の中を
array[i]= *p
から*k =*p
にしたことです
みなさんありがとうございます
194ポイント を手に入れた。
|
|
|
|
|
Name: バグ ..ハッカー(214,332ポイント)
Date: 2010/09/13(月) 15:53
No:61649
|
|
Title: Re:ポインタを使った文字列交換
|
|
解決したようだけど、scanf関数は使ってはいけないのでしょうか?
#include <stdio.h>
#define BUFFER_SIZE 20
void swap_string(char str1[], char str2[])
{
char tmp;
int i;
for (i = 0; i < BUFFER_SIZE; ++i)
{
tmp = str1[i];
str1[i] = str2[i];
str2[i] = tmp;
}
}
void swap_stringWithPointer(char* str1, char* str2)
{
char tmp;
int i;
for (i = 0; i < BUFFER_SIZE; ++i)
{
tmp = *(str1 + i);
*(str1 + i) = *(str2 + i);
*(str2 + i) = tmp;
}
}
int main(void)
{
char x[BUFFER_SIZE + 1] = {0, };
char y[BUFFER_SIZE + 1] = {0, };
printf("文字列x (20字まで)? ");
scanf("%20s%*[^\n]", x);
printf("文字列y (20字まで)? ");
scanf("%20s%*[^\n]", y);
swap_string(x, y);
printf("swap_string\n");
printf("入り替え後のx : %s\n", x);
printf("入り替え後のy : %s\n", y);
swap_stringWithPointer(x, y);
printf("swap_stringWithPointer\n");
printf("入り替え後のx : %s\n", x);
printf("入り替え後のy : %s\n", y);
return 0;
}
300ポイント を手に入れた。
|
|
|
|
|
Name: blue ..初心者(6,653ポイント)
Date: 2010/09/13(月) 22:55
No:61678
|
|
Title: Re:ポインタを使った文字列交換
|
|
scanfでもできます。fgetsだと出力のあとprintf("\n");で改行する必要はないですが、scanfだとしなければいけません。
55ポイント を手に入れた。
|
|
|
|
|
Name: バグ ..ハッカー(214,376ポイント)
Date: 2010/09/14(火) 03:14
No:61686
|
|
Title: Re:ポインタを使った文字列交換
|
|
おっと、失礼しました。fgetsに変更したというのを読んでいませんでしたm(_ _)m
2倍のポイントを手に入れた! 44ポイント を手に入れた。
|
|
|
|
Name: 名無しのプログラマ ..ぴよぴよ(115ポイント)
Date: 2010/09/13(月) 00:50
No:61633
|
|
Title: レイヤーをつかったプレイヤーの描画
|
|
こちらの掲示板はいつも参考にさせていただいております。
現在製作中のRPGのユニット描画処理で、悩んでいる事があります。
1、ベースとなるマップの描画(32x32)
2、プレイヤー画像の描画(32x64)
3、NPCなどのオブジェクトの描画(32x64)
4、重なるレイヤー2マップの描画(32x32)
※ カッコ内は画像サイズです。
上記の順にデータを描画し、表示する関数を作製したのですが、
1と4は2と3を描画する前、描画した後に描画すればいいのですが、
肝心のユニット描画で、forのなかにforを利用するというn~nのような状態になってしまいます。
// ベースマップの描画
〜
// ユニットをX,Yの小さいほうから描画
// (PLAYERを描画後、NPCを描画すると、PLAYERのサイズ上、頭にかさなってしまうため)
for(int i = 0; i < MapSizeY; i ++)
{
for(int j = 0; j < MapSizeX; j ++)
{
// Playerの座標XとYが描画位置と等しいものを描画
for(int idx = 0; idx < PlayerCount; idx ++)
{
if(Player[idx]->GetPosX() == j && Player[idx]->GetPosY() == i) DrawPlayer(idx);
}
// Npcの座標XとYが描画位置と等しいものを描画
for(int idx = 0; idx < NpcCount; idx ++)
{
if(Npc[idx]->GetPosX() == j && Npc[idx]->GetPosY() == i) DrawNpc(idx);
}
〜以下同様の処理〜
}
}
// レイヤー2マップの描画
〜
これでも問題なくうごくのですが、どうにもふに落ちません。
ユニット専用の配列データ(UnitDataMap[MapSizeY][MapSizeX])に
ユニットのタイプ(Player,Npc,etc...)と管理番号を保持して描画など考えて見ましたが、
ユニット同士がかさなる場合があるため、可能であれば他の手法をとりたいです。
もっと効率的な方法などありましたら、教えていただけないでしょうか。
よろしくおねがいします。
115ポイント を手に入れた。
|
|
|
|
Name: 名無しのプログラマ ..ぴよぴよ(205ポイント)
Date: 2010/09/13(月) 00:52
No:61634
|
|
Title: Re:レイヤーをつかったプレイヤーの描画
|
|
>>ユニット専用の配列データ(UnitDataMap[MapSizeY][MapSizeX])に
ここにユニットの数と複数データを保有できるようにすればいけるかもしれませんでした・・・。
ただ、せっかくなので皆さんの使用している方法があれば聞いてみたいです。
90ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(577,120ポイント)
Date: 2010/09/14(火) 00:00
No:61682
|
|
Title: Re:レイヤーをつかったプレイヤーの描画
|
|
PlayerCount個分の int型を格納できる配列やコンテナに表示する順にソートしたインデックス番号を格納し、
for文で DrawPlayer(indTbl[i]) なかんじで表示、ってところでしょうか。
68ポイント を手に入れた。
|
|
|
|
Name: LUNA ..初心者(6,921ポイント)
Date: 2010/09/13(月) 16:39
No:61650
|
|
Title: <質問>あるクラス内の関数で同クラスの別関数を使用できるか?
|
|
かなり久しぶりの投稿です。
今回みなさんに伺いたいのは、あるクラスがあるとして、そのクラスの関数内で同じクラス内の別の関数が使用できるかどうかです。
現在私は学校のプログラムでひとつに繋がったプログラムをファイル分けしてコンパクトにしようとしているんですが、その中で
//------------------------------------------------------------------------------------------
// 関数名:SmokeInit SmokeInit(gl_Ball[i].Pos,16,20.0f,0,0,0);
// 内 容:煙更出現処理
//------------------------------------------------------------------------------------------
void SmokeInit(D3DXVECTOR3 Pos,int AniStart,float Size,int RotXRand,int RotZRand,int MoveFlg)
{
SMOKE *p;
D3DXMATRIX RotMx;
D3DXVECTOR3 RotAxis;
p = (SMOKE *)malloc(sizeof(SMOKE));
if(p != NULL){
p->Pos = Pos;
p->Ani = AniStart;
p->Size = Size;
p->ACnt = 0;
p->RotX = ((float)(rand()%(RotXRand*2+1))-RotXRand)/10;
p->RotZ = ((float)(rand()%(RotZRand*2+1))-RotZRand)/10;
p->Speed = 0;
if(MoveFlg != 0){
RotAxis = p->Pos - gl_LookVec;
p->Speed = (((float)(rand()%30+20))/100);
p->Move = D3DXVECTOR3(0,1,0);
D3DXMatrixRotationAxis(&RotMx,&RotAxis,D3DXToRadian(rand()%360));
D3DXVec3TransformCoord(&p->Move , &p->Move , &RotMx);
}
ZSortInit(p,SmokeDraw,SmokeUpdate,p->Pos);<----ここ。記述してある2つの関数は共にアドレス
}
}
と、SmokeInit内で同系列のSmokeDraw,SmokeUpdateアドレスを記述してあるのを見つけました。
Smoke関連(Init,Update,Draw)を一つのクラスにまとめようとしたらそのクラス内の関数で同じクラスで別の関数を使用することになってしまいます。記述もややこしくなるだろうし、何よりもそんなことが可能なのか、どうかが分からなくて困っています。もしわかる方がいらっしゃれば、アドバイスしていただけると幸いです。
もし出来る場合は記述方法も教えていただけると幸いです。下手な説明ですみません。これだけだと分かりにくいと思いますので一応元のプログラムをつけときます。これはエラーを起こさずにちゃんと動いたものです。
846ポイント を手に入れた。
|
|
|
|
Name: MNS ..熟練のプログラマー(41,000ポイント)
Date: 2010/09/13(月) 17:50
No:61654
|
|
Title: Re:<質問>あるクラス内の関数で同クラスの別関数を使用できるか?
|
|
>あるクラスがあるとして、そのクラスの関数内で同じクラス内の別の関数が使用できるかどうか
できます。
使うだけなら別にややこしくはありません。
class Smoke
{
void Update();
void Draw();
public:
void Init(){
Update();
Draw();
}
Smoke();
~Smoke();
};
質問は、恐らく、メンバ関数のポインタの扱いについでだと思います。
可能ではありますが、記述が厄介です。
まず、メンバ関数ポインタの型についてですが、上のSmokeクラスを例にとると、
UpdateおよびDraw関数の型は、"void(Smoke::*A)()"などとなります。
アドレスを渡すときは、&Smoke::Update; と記述して渡します。
問題は、その呼出についてです。
たとえば、
void Call(void(Smoke::*A)(), void(Smoke::*B)());
という関数を作り、それにUpdateとDrawのアドレスを渡すとすると、
Call(&Smoke::Update, &Smoke::Draw);
という記述になりますが、
このCall関数がSmokeクラスのメンバ関数か否かで変わってきます。
なぜなら、メンバ関数ポインタでメンバ関数を呼び出すとき、
インスタンスを通じて呼び出す必要があるからです。
メンバ関数であれば、
void Smoke::Call(void(Smoke::*A)(), void(Smoke::*B)())
{
(this->*A)();
(this->*B)();
}
という記述で引数にとった関数を呼び出すことが出来ます。
メンバ関数でなければ、
void Smoke::Call(void(Smoke::*A)(), void(Smoke::*B)(), Smoke* p_smoke)
{
(p_smoke->*A)();
(p_smoke->*B)();
}
や、
void Smoke::Call(void(Smoke::*A)(), void(Smoke::*B)())
{
Smoke smoke;
(smoke.*A)();
(smoke.*B)();
}
などという記述になりますが、後者は恐らく使えないでしょう。
450ポイント を手に入れた。
|
|
|
|
|
Name: LUNA ..初心者(7,030ポイント)
Date: 2010/09/13(月) 23:02
No:61679
| 解決!
|
Title: Re:<質問>あるクラス内の関数で同クラスの別関数を使用できるか?
|
|
へたくそな説明にもかかわらず回答してくれてありがとうございます。
今までエラーが潰せないと思ったら、アドレスだと表記がややこしくなるんですね・・・
まだ理解できてない部分(というか夏休みによるボケが抜けてない)もあるのでじっくりと理解させてもらいます。
本当に回答してくれてありがとうございます。
109ポイント を手に入れた。
|
|
|
|
Name: 七氏 ..かけだし(1,864ポイント)
Date: 2010/09/13(月) 11:04
No:61640
|
|
Title: 数列→文字列の処理
|
|
以下のようなプログラムでfopenのstraに"text_data100.txt"と入れたいのですが、numberを数字(100)から文字列("100")に変更する方法を教えていただけないでしょうか?
numberを文字列に変更することが出来たら、文字列同士の結合はstrcat(a,b)でする予定です
C言語はまだ素人ですが過去にRubyを勉強したことがあり、その時はnumber.to_sという処理で同等のことをしていました
int main(void)
{
FILE *fo;
char stra[50]="text_data";
int number=100;
char strc[5]=".txt"
//ここの間の処理
fo=fopen(stra,"rb");
}
今から出かけるので返信が遅くなってしまうかもしれません
よろしくお願いします
2倍のポイントを手に入れた! 630ポイント を手に入れた。
|
|
|
|
Name: ideyan ..中級者(10,705ポイント)
Date: 2010/09/13(月) 11:19
No:61641
|
|
Title: Re:数列→文字列の処理
|
|
sprintf(stra,"text_data%d.txt",number);
聞かれている方法とは違いますが、
この方法でどうでしょうか?
52ポイント を手に入れた。
|
|
|
|
|
Name: びっくす ..ぴよぴよ(166ポイント)
Date: 2010/09/13(月) 11:22
No:61643
|
|
Title: Re:数列→文字列の処理
|
|
サンプルです。
sprintf関数を使った方が文字列の連結は簡単に出来ると思います。
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE *fo;
char *stra = "text_data";
char *strb =".txt";
char strc[50];
int number = 100;
sprintf(strc, "%s%d%s", stra, number, strb);
printf("%s\n", strc);
return 0;
}
184ポイント を落としてしまった。
|
|
|
|
|
Name: けえぼお ..かけだし(2,218ポイント)
Date: 2010/09/13(月) 20:00
No:61663
|
|
Title: Re:数列→文字列の処理
|
|
STLを使ってみては?
#include <stdio.h>
#include <string>
#include <sstream>
int main( void )
{
FILE *fo;
char *stra = "text_data";
int number = 100;
char *strc = ".txt";
std::ostringstream cOSStream;
cOSStream
<< stra
<< number
<< strc;
fo = fopen( cOSStream.str().c_str(), "rb" );
if( fo == NULL )
return -1;
// 何らかの処理
fclose( fo );
return 0;
}
188ポイント を落としてしまった。
|
|
|
|
|
Name: 七氏 ..かけだし(1,924ポイント)
Date: 2010/09/13(月) 21:45
No:61671
| 解決!
|
Title: Re:数列→文字列の処理
|
|
遅くなりました
sprintfを知らなかったため、とても参考になりました
これでやりたかったことの大半が出来るようになりそうです
本当にありがとうございました
60ポイント を手に入れた。
|
|
|
|
Name: 宗一郎 ..かけだし(1,081ポイント)
Date: 2010/09/13(月) 16:47
No:61651
|
|
Title: フローチャートについて
|
|
それなりの規模のプログラムを組む際には、まずフローチャートを作るように大学の先輩に教えてもらいました。
それで、Excelの図記号でフローチャートを作っていたのですが、いまいち効率がよくありません。
どなたか、使いやすいエディタなどを教えていただけないでしょうか。
よろしくお願いしますm(_ _)m
135ポイント を手に入れた。
|
|
|
|
Name: ookami ..熟練のプログラマー(52,301ポイント)
Date: 2010/09/13(月) 17:27
No:61652
|
|
Title: Re:フローチャートについて
|
|
「UML フリー」あたりで検索すると、たくさん出てくるとは思いますが、
考えをまとめるなら 手書き をおすすめします。
レポートなどに貼り付けるなら、手書きでまとめたものを
エクセルで書き直すのがいいです。
というのは、別の人にデータで渡す時、
エクセルなら相手も持っている可能性が高い(そこらのフリーソフトよりは)
からです。
ついでに、エクセルの「コネクタ」はご存知ですか?
図形同士を勝手につないでくれます。
151ポイント を手に入れた。
|
|
|
|
|
Name: 初級者 ..中級者(9,723ポイント)
Date: 2010/09/13(月) 17:46
No:61653
|
|
Title: Re:フローチャートについて
|
|
フローチャートのことを知りたい人にUMLについて
調べるよう促すのは、的はずれです。
25ポイント を手に入れた。
|
|
|
|
|
Name: 宗一郎 ..かけだし(1,240ポイント)
Date: 2010/09/13(月) 18:10
No:61656
|
|
Title: Re:フローチャートについて
|
|
ookamiさん、初級者さん回答ありがとうございますm(_ _)m
>>ookamiさん
やはり自分用は手書きがいいんですね^^
コネクタは知りませんでした><
今まで線で地味につなげていました(´・ω・`)
ありがとうございます^^
>>初級者さん、がくせいさん
すみません。それではどのように調べたほうがいいですか?
教えてもらえると助かりますm(_ _)m
159ポイント を手に入れた。
|
|
|
|
Name: びっくす ..ぴよぴよ(350ポイント)
Date: 2010/09/13(月) 10:28
No:61638
|
|
Title: 動的メモリ確保と解放について
|
|
初めまして。びっくすと申します。
環境はxp, vc++2008, c言語になります。
現在メモリの動的確保を行う関数と解放を行う関数を自作しております。
そこで少し詰まってしまったので、教えていただけないでしょうか?
#include <stdio.h>
#include <stdlib.h>
int Malloc(int **a)
{
*a = (int *)malloc(100 * sizeof(int));
if (!*a) {
return -1;
}
return 0;
}
void Free(int *a)
{
if (a) {
free(a);
}
}
int main(void)
{
int *a;
Malloc(&a);
Free(a);
return 0;
}
上記サンプルコードでFree関数の部分なのですが、
仮引数をダブルポインターにする必要があるでしょうか?
もしくはこのままでいいでしょうか?
ご返答よろしくお願いします。
350ポイント を手に入れた。
|
|
|
|
Name: びっくす ..ぴよぴよ(234ポイント)
Date: 2010/09/13(月) 13:36
No:61648
| 解決!
|
Title: Re:動的メモリ確保と解放について
|
|
>ポインタを書き換えるわけではないので構わないと思います。
ただ、解放後にポインタ値をFree側でNULLにしたいならダブルポインタにしないといけません。
分かりやすい説明ありがとうございます^^
理解できました。
68ポイント を手に入れた。
|
|
|
|
Name: どもどもも ..ぴよぴよ(246ポイント)
Date: 2010/09/13(月) 12:30
No:61647
|
|
Title: ストリーミング
|
|
知りたいことは
・一般的なストリーミングのプロトコルは? RTCP?
・ダイナミックにストリーミングするときのアーキテクチャは?
スケールアウトし易い方向でお願いします。
<適当な予想図>
[User] <------ [ストリーミングサービス]
↑
|
|
[ ストリーミングデータストレージサービス ]
↑
|
|
[User] - Data -> [イベントハンドルサービス]
・参考になるソースは?
Darwin Streaming Server
http://dss.macosforge.org/
とかで、ダイナミックにStreamingするなら、ここら辺が参考になるとか
お願いします。
です。
よろしくお願いします
246ポイント を手に入れた。
|
|
|
Name: たろ ..中級者(11,991ポイント)
Date: 2010/09/07(火) 00:27
No:61171
|
|
Title: [画像処理]レイヤー合成の高速化について
|
|
お世話になっております。
C言語というか、画像処理の話なのですが、ご意見頂ければ幸いです。
ペイントやPhotoshopのような画像加工ソフトを作ろうとしています。
よくあるレイヤー機能を持たせたく、実装してみましたが、レイヤービットマップの合成
(アルファブレンド)処理が遅くて、もっと速くならないかと悩んでます。高速化のために、
効果的な方法はないでしょうか?
環境:WinXP Home (SP3)、VC++2008EE、C言語、Win32API
今の実装(※1)は、レイヤーが何枚かある状態で、ユーザが「レイヤーの透明度を変更」
「レイヤーの可視・不可視を切り替え」するたびに、
1) 全レイヤービットマップ(32bit)をなめて合成ビットマップ(24bit)を作る
2) 合成ビットマップを画面に表示
しています。
画像が大きいほど、レイヤーの枚数が多いほど、1) 合成ビットマップを作る処理 が
どんどん重くなっていきます。(CPU: Core Duo 1.6GHz)
・2000x2000ピクセルのレイヤー2枚合成するのに、約0.2秒
・4000x4000ピクセル 〃 、約0.7秒
・5000x5000ピクセル 〃 、約1.2秒
・ 〃 3枚合成するのに、約1.3秒
・ 〃 4枚合成するのに、約1.4秒
一方、私は「SAI」という5千円くらいのペイントソフトを使っていますが、このソフトは
同様の操作が、比べものにならないくらい高速なんです。大きな画像でも、レイヤーが
何枚あっても、「レイヤー透明度の変更」や「レイヤー可視・不可視の切り替え」は
一瞬でおわります。私の実装からすると信じられない速さです。
無い知恵を絞って、「浮動小数点演算は使わない」「乗除算を減らす」「除算はビットシ
フトで代替」などのC言語的な小手先の?高速化は施したつもりですが、まったくSAIとい
うソフトの足元にも及びません。
SSEやアセンブラによる高速化はちょっと敷居が高くて未経験なのですが、「画像が大き
いほど、レイヤー枚数が増えるほど遅くなる」という傾向を感じなくする程の効果がある
のかどうか・・?もっと、根本的なデータ構造やアルゴリズムが違うのではないか・・?
「1つのレイヤー透明度を変えただけで全部のレイヤーをなめているから遅い」のかな?
ただ、レイヤーの合成結果をキャッシュしておく?よい方法も思い浮かびません。
なにか定石的なアルゴリズムなどあればよいですが、見つかりません。
大きな画像になるほど合成に時間がかかるのは仕方ない、とも思うのですが、SAIという
ソフトにはそのような傾向は微塵も感じられません。不思議すぎます・・。
という感じなのですが、画像処理ソフトのレイヤー機能の実装方法について、高速化の
ためのよい方式などはないでしょうか?よろしくお願いします。
(※1)現在のレイヤー合成処理の概要
・レイヤー1枚には、32bit(RGBA)DIBデータ1つ、透明度値(0〜255)1つがある。
・ビットマップの先頭から最後まで1ピクセルずつ、
・上層レイヤーから下層レイヤーに向かって、
・ピクセル透明度とレイヤー透明度を考慮した係数を、レイヤーピクセルRGB値に乗算し、
・合成ビットマップ(24bitDIB)ピクセルRGB値に加算していく。
・コードの雰囲気は以下のような感じです。(実際はもっとごちゃごちゃしてます)
/* レイヤー1つの型(片方向リスト用) */
struct LayerNode {
DIB32 Bitmap; /* 32bitビットマップ(RGBA)データ */
BYTE Alpha; /* レイヤー透明度(0〜255) */
BOOL Visible; /* 可視・不可視状態 */
struct LayerNode *next; /* 次(下)のレイヤー */
};
/* 合成ビットマップ作成 */
for( n=0; n<=ビットマップ最終ピクセル位置; n++ )
{
R = G = B = 0; /* 合成ビットマップピクセル値 */
for( layer=最上層レイヤー; layer; layer=layer->next )
{
if( !layer->Visible || !layer->Alpha ) continue; /* 不可視・完全透明 */
係数 = ピクセル透明度(layer->Bitmap->Pixel[n].A)と
レイヤー透明度(layer->Alpha)を考慮して算出
R += 係数 * layer->Bitmap->Pixel[n].R
G += 係数 * layer->Bitmap->Pixel[n].G
B += 係数 * layer->Bitmap->Pixel[n].B
}
合成ビットマップ->Pixel[n].R = R;
合成ビットマップ->Pixel[n].G = G;
合成ビットマップ->Pixel[n].B = B;
}
/* 画面表示 */
StretchDIBits相当の処理( 合成ビットマップ );
1,844ポイント を手に入れた。
|
|
|
|
Name: ISLe ..上級者(18,000ポイント)
Date: 2010/09/07(火) 02:02
No:61192
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
UINT32の変数にA8R8G8B8のピクセルデータが入っているとしてレイヤー透明度0〜255を掛ける場合、
UINT32 pixel_argb; // 元のピクセルデータ
UINT8 layertrans; // レイヤー透明度(0〜255)
UINT32 pixel_0r0b = pixel_argb & 0x00ff00ff;
UINT32 pixel_00g0 = pixel_argb & 0x0000ff00;
pixel_0r0b = ((pixel_0r0b * layertrans) / 255) & 0x00ff00ff;
pixel_00g0 = ((pixel_00g0 * layertrans) / 255) & 0x0000ff00;
// ↓のほうが高速だけど誤差があったようななかったような
//pixel_0r0b = ((pixel_0r0b * (layertrans+1)) >> 8) & 0x00ff00ff;
//pixel_00g0 = ((pixel_00g0 * (layertrans+1)) >> 8) & 0x0000ff00;
pixel_dest = pixel_0r0b | pixel_00g0;
とするのが割と速いと思います。
ピクセル透明度(いわゆるアルファチャンネル)については、SAIにはその機能自体が無いようです。
Photoshopでは新規作成したデフォルトのレイヤーにアルファチャンネルは無くて、アルファチャンネルを追加したレイヤーだけがアルファチャンネルを持つので特定のレイヤーだけに計算を絞ることができます。
またメモリを食いますがアルファチャンネルは事前計算しておくことも可能です。
--追記
> 「浮動小数点演算は使わない」「乗除算を減らす」「除算はビットシフトで代替」
既に対策しているとありますね。すみません。 
338ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(12,364ポイント)
Date: 2010/09/07(火) 03:38
No:61194
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさんありがとうございます。
> UINT32 pixel_0r0b = pixel_argb & 0x00ff00ff;
> UINT32 pixel_00g0 = pixel_argb & 0x0000ff00;
> pixel_0r0b = ((pixel_0r0b * layertrans) / 255) & 0x00ff00ff;
> pixel_00g0 = ((pixel_00g0 * layertrans) / 255) & 0x0000ff00;
> pixel_dest = pixel_0r0b | pixel_00g0;
な、なんですかこの計算方法・・初めて見ました。こんなやり方があるんですか。
ええと・・例えば、0x00ff00 * 255 というのは、下位8ビットを無視すると、0x00ff * 255 と同じ、
ということ・・ですよね・・。そうなのか・・。
あと、1〜255の範囲で掛けたり割ったりするぶんには、0xffff を超えないから大丈夫、という条件も
合わさってできる方法でしょうか。
うーんこんなのとても思いつかないなぁ・・すごい。
ありがとうございました。ちょっと試してみたいと思います。
あ、あとさらに、合成ビットマップも32bitじゃないとダメですね。
今は24bitだから、変えないとダメか。メモリ使用量がちょと増えるけど致し方あるまい。。
> ピクセル透明度(いわゆるアルファチャンネル)については、SAIにはその機能自体が無いようです。
えっ、そうなんですか。
半透明な感じのブラシで塗るときは、ピクセル透明度を使ってると思ってました。
Photoshopのレイヤーも既定ではアルファチャネルがない・・そうだったのか・・。
でもそうすると、不思議なのですが・・、下のレイヤーが透けて見える感じの薄いブラシで塗っていくと、
下のレイヤーが「よく透けて見える部分」と「あまり透けてない濃い部分」のグラデーションのような状態
になると思いますが、こういうのを24bitのRGBだけでどうやって実現するんだろう・・。
> またメモリを食いますがアルファチャンネルは事前計算しておくことも可能です。
「乗算済みアルファ」という言葉を、どこかのサイトで見たことがあります。
アルファチャネルを掛けた値をキャッシュのような形で保持しておく感じでしょうか。
軽く想像してはみましたが、本当にメモリ使用量が増えそうです・・恐ろしい・・。
>> 「浮動小数点演算は使わない」「乗除算を減らす」「除算はビットシフトで代替」
> 既に対策しているとありますね。
あ、いえこの辺りはぜんぜん自信はないです。自分の思いつく限りというだけで・・。
373ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(12,767ポイント)
Date: 2010/09/07(火) 12:38
No:61205
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
シエルさん
> ビット演算は理解されてますか?
人に解説できるくらい理解してるか?と言われると怪しいですね・・・「使ってます」くらいかな。
ちなみに「初めて見た」というのは、(&演算や|演算を見たことがない、という事ではなく)
RGB値の計算方法として初めて見た、1回の演算でビットの途中途中にある2つの数値(RGB)を
一気に演算するとは・・その発想はなかった(笑)という感じでした。
有名なやり方なんですかねぇ・・?
ビット演算と言われると、使っていたのは、
(1) 状態管理フラグで、複数同時にON/OFFになる時はまとめてビットフラグで
#define STATE1 0x001
#define STATE2 0x002
if( (flag & STATE1) && (flag & STATE2) ) …
(2) 2の倍数(2,4,8,…)で乗除算する時は(符号に気をつけて)ビットシフトで
n = n << 1; /* ×2 と同じ */
n = n >> 2; /* ÷4 (余り切り捨て)と同じ */
(3) 小数点以下の精度より速度優先の場合は、float/doubleでなく整数型を固定小数点型として
n = n << 12; /* 小数部12bit固定小数に変換 */
:
/* n を掛けたり割ったり */
:
n = n >> 12; /* 整数に戻す(小数部切り捨て) */
の3種類くらいかなぁ・・。固定小数はこちら↓のサイトを参考にそのまま使ってます。
http://www.sage-p.com/compone/toda/fixdec.htm
403ポイント を手に入れた。
|
|
|
|
|
Name: ookami ..熟練のプログラマー(51,316ポイント)
Date: 2010/09/07(火) 13:18
No:61209
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
61192で、
> // ↓のほうが高速だけど誤差があったようななかったような
とあったので、ざっくりですが、検証してみました。
添付ファイルを参照下さい。
アルファ値が小さいほど偏差が大きくなりますが、
最大でも0.0039なので、RGB各0〜255の範囲なら、
±1でるかどうか、といったところですね。
人間が見ても分からない範囲でしょうから、
表示時は高速な方、
ファイル保存時は正確な方、
といったところでしょうか。
※ すいません、言葉的には「偏差」じゃなくて「誤差」かも。
13ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(13,154ポイント)
Date: 2010/09/07(火) 13:44
No:61210
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ookamiさん
ありがとうございます。
> Zバッファで多少早くなるかも?
3次元コンピュータグラフィックスのテクニックのようですが、2次元のお絵描きソフトにも応用
できるんでしょうか。考えたことがなかったです。Zバッファのプログラムも作ったことないので、
まずは勉強から・・調べてみたいと思います。
> あとは、画面外の計算を省略するとか...
表示のズーム処理では、いちおう画面外の計算を省略していますので、今回のレイヤー合成でも
考えてみました。が、どうも採用には至らずで・・。画像全体を表示している状況を考えると、
結局ぜんぶ合成しないといけないし・・という辺りで私の頭では限界でした(^^;
SAIは1ピクセル64bitなんですか。知らなかった・・。
型でいうと、UINT64/ULONGLONGで扱うことになるのかな。確かにSAIはメモリ使用量は多いです。
でもそれであんなに高速に動作しているのがすごい・・。単純に64bit型に置き換えるというのは
CPU/OSが32bit環境だとかなり遅くなりそうな気がします。MMX/SSEを使わないと…となりそうな。
SSEとかちょっと敷居が高くて手を出せてませんorz
SAIの更新履歴、ほとんど不具合修正に見えますが、高速化もチラホラありますね。アルゴリズム
までわかるようなのは少ないですが・・。比較対象としてはちょっとレベル高すぎとは思います・・。
387ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(13,525ポイント)
Date: 2010/09/07(火) 14:10
No:61211
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
palladiumさん
ありがとうございます。
画面表示処理(VRAM転送ていうんでしょうか)の高速化も、確かに気になる要素ではありました。
レイヤー合成処理と画面表示処理を順番じゃなくて一緒にやってしまう、という想像もしましたが、
ソースが手に負えなくなると思ってやめました・・。
GDI+ は「遅い」という噂もあって、使ってみたことはありませんでした。やっぱり遅いんですかね。
あと DDB も実は使ってません・・。今は、DIB を SetDIBitsToDevice() で画面に送っています。
DDB の方が多少速いらしいという噂も目にしつつ、ちょっと取り扱いAPI(CreateCompatibleDCとか)が
独特すぎて敬遠してしまってます。。
さらに新しい噂では、GDI関数はDirectX系のAPIをラップするだけになるとか何とか見たような??
ブラウザまでGPU支援機能を使うようになったりして、「高速化」と言いつつGDIしか使ってないのは
時代遅れなのかなぁ・・と思いつつ、DirectX まだ未経験です(^^;
371ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(13,662ポイント)
Date: 2010/09/07(火) 14:30
No:61212
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ookamiさん
すごい、貴重な情報をありがとうございます。m(_ _)m
仕事はやいですねぇ〜。
なるほど、見た目には違いは判別できない程度の差ですかね。
それなら速い方を使いたいです。実際に画像で比べてみたいと思います。
ただ、自分のプログラムはちょっとまだ手付かずでした・・。
137ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(18,218ポイント)
Date: 2010/09/08(水) 02:31
No:61254
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
最初にすみません。
ピクセル透明度はいわゆるアルファチャンネルではありませんでした。
ソフトの機能と概念をごっちゃにしてました。
SAIには透明度だけを分離して編集する機能はないですがピクセルごとの透明度は持ってます。
ピクセルごとの透明度がないと水彩っぽい塗りできないですもんね。
件のコードはゲームでフェードイン/フェードアウトの演出で使われる感じのものです。
今回は精度を落としてはいけない用途なのでトリッキーレベル1というところです。
ookamiさんが検証してくださったとおり誤差は表面化しないので高速版を使ってください。
Zバッファは不透明ピクセルに出会ったらそれより下のレイヤーを計算しないように、ピクセルと同じ数のバイト配列などを用意してマークしていく感じの仕組みになると思います。
アニメっぽい塗りの絵には有効と思いますが水彩っぽい塗りの絵には逆効果になるかもしれません。
218ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(14,049ポイント)
Date: 2010/09/08(水) 12:42
No:61266
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさん
私もピクセル透明度とアルファチャンネルは同じ意味だと思ってました・・。
ググッてもそういう説明が多いですし。でも確かにPhotoshopだとちょっと違うようで、
アルファチャンネルというバッファの編集ができるとか何とか?よくわかりませんが。
ひとまず水彩っぽい塗りにはピクセル透明度が必要、ということで安心しました。
なるほどゲームのフェード効果で使われているんですね。
ここはゲームの実装に詳しい方が多いですね。
Zバッファの考え方もありがとうございます。レイヤーがZ軸に相当するんですね。何となく想像できました。
実は、「不透明ピクセルに出会ったらそれより下のレイヤーを計算しない」は、ピクセル毎に
「 if( 透明度==255 ) { レイヤーループ抜ける; } 」という処理に、既になっていました。
Zバッファ方式で別にバッファを持つのは・・ちょっと悩みます・・。
自アプリの改造状況ですが、
とりあえずレイヤービットマップ32bit、合成ビットマップ24bitは変えずに、
高速版の計算方法だけを取り入れてみました。少し速くなりました。
10%くらいかな?1.0秒が0.9秒になった、くらいの感じです。
ookamiさんが計算してくれた 0.003 前後の誤差も、私の目にはまったく問題ありません。
ということで解決、でよいかなと思いましたが・・
やはりビットマップの32bit→24bit変換も一緒にやってるのが遅い気がするので、
両方32bitにしてみたいと思います。その報告で解決とさせて頂きたいと思います。 
387ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(14,571ポイント)
Date: 2010/09/08(水) 22:52
No:61316
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
自アプリであれこれ試してみた結果を報告します。
25%くらい速くなりました。
(1) 0x00ff00ff, 0x0000ff00 マスクを使ったRGB計算(高速版)で 10%くらい
(2) 32bit→24bitをやめて32bit→32bitにして、ループ処理を単純化して 10%くらい
(3) ループ内で呼び出していた関数をベタ書き(関数呼び出しコスト削減)で 5%くらい
例えば、3000x3000ピクセルの半透明レイヤー5枚の合成にかかる時間が、
1.0秒台だったのが、0.7秒台くらいになりました。
皆様いろいろ教えて頂きありがとうございました。m(_ _)m
これで本件は解決とさせて頂きます。
それにしても、「このソフト軽くて速くていいなー」なんて何気に使っていたソフトを
作った人のすごさを思い知った次第です。
編集:解決マークはずしました。 
2倍のポイントを手に入れた! 522ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(18,403ポイント)
Date: 2010/09/09(木) 02:16
No:61325
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
#解決してた。
テーブルを用意してレイヤー間の合成処理を高速化する方法があります。
UINT8 layer1_r;
UINT8 layer2_r;
UINT8 dst_r;
// 「レイヤー1のデータ * 256 + レイヤー2のデータ」のインデックスに予め合成計算結果を入れておく
// RGB共通・合成方法別に用意すると良い
UINT8 table[65536];
dst_r = table[(layer1_r << 8) | layer2_r];
// RGBそれぞれに対して計算
インデックスの計算だけになるのと、オーバーフローやアンダーフローも考慮しなくて良いので速くなります。
オーバーフローやアンダーフローへの考慮はテーブル作成時に盛り込まれているので。(←追記)
共用体使って32ビットピクセルデータからRGB各要素を直接参照するとかは既にやってますかね。
最終的に24ビットに落とすのは影響少ない気がします。

185ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(13,870ポイント)
Date: 2010/09/09(木) 12:36
No:61347
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさんありがとうございます!
解決というか、「もう他に思いつかないので終わり」という感じでした。
新しい話もらったので解決マーク外させてもらいます。
> テーブルを用意してレイヤー間の合成処理を高速化する方法があります。
なるほど、ルックアップテーブルと呼ばれたりする考え方でしょうか?
でも「レイヤー間の」というあたりがよく分かりません・・。
> UINT8 layer1_r;
> UINT8 layer2_r;
> UINT8 dst_r;
>
> // 「レイヤー1のデータ * 256 + レイヤー2のデータ」のインデックスに予め合成計算結果を入れておく
> // RGB共通・合成方法別に用意すると良い
> UINT8 table[65536];
>
> dst_r = table[(layer1_r << 8) | layer2_r];
> // RGBそれぞれに対して計算
「レイヤー1,2のデータ」とは、RGBの値のことですよね。(layer1_r,layer2_r)
例えば、「レイヤー1のR値」と「レイヤー2のR値」から「合成したR値」が決まる、ということ・・?
あれ、透明度は?レイヤー透明度とピクセル透明度はどこで考慮するのでしょうか・・??
> インデックスの計算だけになるのと、オーバーフローやアンダーフローも考慮しなくて良いので速くなります。
> オーバーフローやアンダーフローへの考慮はテーブル作成時に盛り込まれているので。
すみませんここもよく分からないのですが、([256][256]の2次元配列でなく)[65536]の1次元配列にして、
table[(layer1_r << 8) | layer2_r] のように使うこと、による効果でしょうか?
でも layer1_r,layer2_r が UINT8 範囲内なら [layer1_r][layer2_r] でも大丈夫そうな気もするな・・。
> 共用体使って32ビットピクセルデータからRGB各要素を直接参照するとかは既にやってますかね。
やってません!
恥ずかしながら共用体って、便利さや必要性を実感したことがなく使ったことがないです・・。
今は、
UINT32 color = *((UINT32*)ビットマップピクセルポインタ);
BYTE A = (BYTE)(color>>24);
BYTE R = (BYTE)(color>>16);
などとやっていました。共用体を使うと、ここら辺が効率よくなるんでしょうか?
こんな↓感じの使い方でしょうか・・??
union PIXEL32
{
struct {
UINT8 B,G,R,A; /* Windows GDI/DIB ではメモリ上 BGRA の順で並ぶ */
} e; /* (element の e) */
UINT32 color; /* 0xAARRGGBB (リトルエンディアンなので逆順) */
};
/* ARGB を直接参照できる */
((union PIXEL32*)ビットマップピクセルポインタ)->e.A
((union PIXEL32*)ビットマップピクセルポインタ)->e.R
あれ、でもこの参照のしかたなら共用体じゃなくても構造体でもできそうな・・?
> 最終的に24ビットに落とすのは影響少ない気がします。
これは、ループ内のカウンタ変数が、32ビット用ピクセル位置と24ビット用ピクセル位置と
2つ必要だったのが、(両方32ビットにすれば)1つだけで済む、というだけの話でした。

732ポイント を落としてしまった。
|
|
|
|
|
Name: ISLe ..上級者(18,803ポイント)
Date: 2010/09/09(木) 22:52
No:61388
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
> でも「レイヤー間の」というあたりがよく分かりません・・。
No:61192のコードは各レイヤーで透明度を掛けたピクセルデータを求める処理でした。
今回はレイヤー同士を合成する部分なので「レイヤー間」と書いたのですが、それまでに合成した画像と各レイヤーの合成処理なので「レイヤー間」はおかしいですね。
たろさんが最初の質問に書かれてたコードは加算合成なんですけど、半透明合成はピクセルの最終的な透明度がT(0〜255)だとしたら、透けて見える(それまでに合成済みの)ピクセルには255-Tの透明度を掛けて、各要素を足し算するので、自分方と相手方の間の計算という意味です。
> すみませんここもよく分からないのですが、([256][256]の2次元配列でなく)[65536]の1次元配列にして、
> table[(layer1_r << 8) | layer2_r] のように使うこと、による効果でしょうか?
例えば加算合成テーブルのtable[128][128]には128と128を足した結果が入っています(そのように準備する)。
ふつうに足したら128+128=256でオーバーフローしてしまうところを255で初期化しておいてそのまま使います。
> UINT32 color = *((UINT32*)ビットマップピクセルポインタ);
> BYTE A = (BYTE)(color>>24);
> BYTE R = (BYTE)(color>>16);
>
> などとやっていました。共用体を使うと、ここら辺が効率よくなるんでしょうか?こんな↓感じの使い方でしょうか・・??
union PIXEL32 pixel;
pixel.color = *((UINT32*)ビットマップピクセルポインタ);
BYTE A = pixel.e.A; // 同じメモリ領域を使っているのでcolorに代入した時点で反映されてる
BYTE R = pixel.e.R;
という感じですね。
逆にARGB要素を変更すればcolorに反映されます。
320ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..中級者(14,419ポイント)
Date: 2010/09/10(金) 03:15
No:61399
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさん
> たろさんが最初の質問に書かれてたコードは加算合成なんですけど、半透明合成はピクセルの最終的な
> 透明度がT(0〜255)だとしたら、透けて見える(それまでに合成済みの)ピクセルには255-Tの透明度を掛けて、
> 各要素を足し算するので、自分方と相手方の間の計算という意味です。
なんとなく、わかりかけてきました。
というか今の加算方式の考え方を変えないとダメかな・・と思いました。
今は、「それまでに合成済みのピクセル」は参照しておらず、最終的な透明度が255を超えないように
計算したRGB値をひたすら積み上げていく感じになっていました。
ちょっとまず「それまでに合成済みのピクセルに255-Tの透明度を掛けて」という感じの処理にするには
どうすればいいか考えたいと思います。たぶん2枚だけ合成するならそうなるのかなーと思うのですが、
3枚以上の合成でどうやるのか・・。やばい、すぐにはできなさそうな予感・・。
ちなみに今のコードは、こちら↓の「Photoshopでの計算方法」の文章を読んで、
http://d.hatena.ne.jp/hajimehoshi/20080420/1208689925
上のレイヤーから順に透明度エネルギーを消費していく、という感じのを自分で適当に作りました。
> 例えば加算合成テーブルのtable[128][128]には128と128を足した結果が入っています(そのように準備する)。
> ふつうに足したら128+128=256でオーバーフローしてしまうところを255で初期化しておいてそのまま使います。
なるほど。配列が1次元か2次元かは関係ないですね。
テーブルの値と使い方はなんとなくわかったような気がします。
ただ、上の話もあってまだ改造イメージは具体的に思い浮かびません。。。
> union PIXEL32 pixel;
> pixel.color = *((UINT32*)ビットマップピクセルポインタ);
> BYTE A = pixel.e.A; // 同じメモリ領域を使っているのでcolorに代入した時点で反映されてる
> BYTE R = pixel.e.R;
> という感じですね。
> 逆にARGB要素を変更すればcolorに反映されます。
なるほど。UINT32で取ってきていおいて、RGBAがすぐに参照できるということですね。
逆にRGBAを個別に変更すればUINT32に直に反映される、というのはいいですね。
いろんな場面で使えそうな気がしてきました。ありがとうございました。
549ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(16,057ポイント)
Date: 2010/09/10(金) 04:14
No:61401
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ちょっと頭がモヤモヤしたまま考えが進まないこともありまして・・
もしよかったら合成処理を行っている関数のソースを見て頂けると助かります。
何か変なことしてないかとか、ここは効率悪いし意味わからんとか・・。
LayerBlendUpdate という関数です。最後に貼りつけます。
独自の構造体を使っているので、この関数を使ったプログラムのソースも添付しました。
複数枚のビットマップを半透明合成するだけのプログラムです。
・起動するとウィンドウが1つ
・ウィンドウにBMPファイルを複数ドラッグ&ドロップすると、勝手に半透明にして合成する
・24ビットWindowsビットマップファイルで同じ縦横サイズのものしか合成できない
目的は、LayerBlendUpdate 関数を高速化したいという話になります。
今の加算合成?のやり方をどう変更すればよいか思案中です・・。
// レイヤー合成処理
void LayerBlendUpdate( void )
{
UINT WxH, pos;
if( !LayerBlend.BIH ) return;
WxH = LayerBlend.BIH->biWidth * LayerBlend.BIH->biHeight; // 全ピクセル数
for( pos=0; pos<WxH; pos++ ) // 先頭から1ピクセルずつ
{
UINT32 blend = 0; // 合成ピクセル値
#define ALPHA_ENERGY_MAX 256
UINT alphaEnergy = ALPHA_ENERGY_MAX; // 合成透明度エネルギーの残り(初期値=最大値)
PLAYER layer;
for( layer=LayerTop; layer; layer=layer->next ) // レイヤー上から順に
{
UINT32 sColor = *((UINT32*)layer->Bitmap + pos); // レイヤーピクセル値
BYTE pixelAlpha = (BYTE)(sColor>>24); // ピクセル透明度
UINT blendAlpha; // 合成透明度
if( !layer->Visible ) continue; // レイヤー非表示スキップ
if( !layer->Alpha || !pixelAlpha ) continue; // 透明スキップ
// エネルギーの残りからこのレイヤーピクセルの合成透明度を決定
if( layer->Alpha==255 && pixelAlpha==255 )
{
// 完全不透明
if( alphaEnergy >= ALPHA_ENERGY_MAX )
{
// 最初(最上層レイヤー)のピクセルが不透明なので単純コピーして終了
blend = sColor;
alphaEnergy = 0;
break;
}
// 不透明なので残りエネルギーぜんぶもらう
blendAlpha = alphaEnergy;
alphaEnergy = 0;
}
else
{
// 半透明=残りエネルギーから透明度割合ぶんだけもらう
// 本来は、レイヤー透明度×ピクセル透明度=255×255段階の精度だが、
// 0x00ff00ff,0x0000ff00マスクを利用した計算を使うため255以下の値に圧縮する
if( layer->Alpha==255 )
{
blendAlpha = (pixelAlpha * alphaEnergy) >>8;
}
else if( pixelAlpha==255 )
{
blendAlpha = (layer->Alpha * alphaEnergy) >>8;
}
else
{
// +1 はなんとなく
blendAlpha = ((layer->Alpha * pixelAlpha + 1) * alphaEnergy) >>16;
}
if( !blendAlpha ) continue;
alphaEnergy -= blendAlpha;
}
// 合成透明度の割合で合成ピクセル値に加算
blend += (((sColor & 0x00ff00ff) * (blendAlpha + 1) >>8) & 0x00ff00ff)|
(((sColor & 0x0000ff00) * (blendAlpha + 1) >>8) & 0x0000ff00);
if( !alphaEnergy ) break; // エネルギーなくなったら終わり
}
if( alphaEnergy )
{
// エネルギーが余ったので、レイヤー背景色(白固定)を加算
UINT tmp = (0xff * alphaEnergy) >>8;
blend += tmp | (tmp<<8) | (tmp<<16);
}
// 合成色1ピクセル決定
*((UINT32*)LayerBlend.Bitmap + pos) = blend;
}
}
1,638ポイント を手に入れた。
|
|
|
|
|
Name: めるぽん ..上級者(19,617ポイント)
Date: 2010/09/10(金) 08:17
No:61405
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
今あまり時間がなくて実際に試す時間が無いのでコードを読んだだけですが、
最終的に白背景に描画するなら、白背景と一つ手前のレイヤをアルファ合成すればアルファ値の残りのエネルギーとか考えなくていい(白背景のピクセルのアルファは必ず1.0だから、合成してもアルファは1.0)ので、
Layer1→Layer2→Layer3
という順番で繋がっているなら、
1.白背景とLayer3を合成
2.1.の画像とLayer2を合成
3.2.の画像とLayer1を合成
とした方が、余りのエネルギーとか考える必要が無くて速いと思います(この順番の単方向リンクリストだとLayer3から処理するとかできないのでデータ構造を少し弄る必要がありますが)。
あと1ピクセル毎に layer を回していますが、アクセスがあっちこっちに行ってしまうので、layer のループの中でピクセルのループを回した方がいいです。そうすれば layer->Visible や layer->Alpha のチェックで無駄に時間を取っている(layer全体で1回判定すればいいだけなのに1ピクセル毎に判定をしている)部分も無くなりますね。
396ポイント を手に入れた。
|
|
|
|
|
Name: めるぽん ..上級者(20,191ポイント)
Date: 2010/09/10(金) 08:45
No:61406
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
こんなイメージ
UINT32* dst; // ← 転送先。全部背景色(今回は 0xffffffff)になっていると思って下さい
LAYER* rLayer; // ← LayerTop が逆になったリストだと思って下さい
for (layer = rLayer; layer; layer = layer->next)
{
if (!layer->Visible || layer->Alpha == 0) continue;
src = ((UINT32*)layer->Bitmap + pos);
int alpha = layer->Alpha; // レイヤ全体のアルファ
for (int n = 0; n < WxH; n++)
{
UINT32 s = src[n];
UINT32 d = dst[n]; // こいつのアルファは必ず 255 のはず
// 各ピクセルのアルファ(ほんとは 255 で割るべき)
int a = ((s >> 24) * alpha) >> 8;
int ra = 255 - a;
// 普通のアルファブレンド処理(ここはもっと速くできる気がする)
dst[n] =
0xff000000 |
(((((s >> 16) & 0xff) * ra + ((d >> 16) & 0xff) * a)) & 0xff00) << 8) |
(((((s >> 8) & 0xff) * ra + ((d >> 8) & 0xff) * a)) & 0xff00) << 0) |
(((((s >> 0) & 0xff) * ra + ((d >> 0) & 0xff) * a)) & 0xff00) >> 8);
}
}
多分間違いはいっぱいあると思いますけど、何となくイメージだけ掴んで貰えれば。
574ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(15,697ポイント)
Date: 2010/09/10(金) 14:13
No:61413
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ぬるぽんさんありがとうございます。
確かにlayer->Visibleなどの判定は無駄に多いとは思ってました。でも回避できなくて・・。
「残りのエネルギーとか考えなくていい」方法というのは、(たぶん理解できてないので)気になる点があるのですが、
エネルギー分配方式だと「下のレイヤーになるほど薄くなる」のですが、これも実現できてしまうのでしょうか?
例えば、あるレイヤーの透明度とビットマップは変わらなくても、上にたくさんレイヤーが重なるほど
どんどん薄くなっていく(結果的に配分される透明度が少なくなっていく)という・・。
いや、すみません、とりあえず頂いたコードイメージを実装してみようかな。
もうちょっとよく考えてみます。
ちなみにプログラム全体のコードを変更したので添付しなおします。
LayerBlendUpdate 関数は(まだ)そのまま変えてません。
操作性がイマイチ合成結果の確認がしにくかったので変えました。
・ファイルを1つずつドロップして上に重ねていけるようにした
・重なっているファイルの順序(レイヤー情報)を表示するようにした
360ポイント を落としてしまった。
|
|
|
|
|
Name: めるぽん ..上級者(20,541ポイント)
Date: 2010/09/10(金) 18:27
No:61424
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
>エネルギー分配方式だと「下のレイヤーになるほど薄くなる」のですが、これも実現できてしまうのでしょうか?
エネルギー分配方式って、Layer1、Layer2 のアルファがそれぞれ 60%、75% だった場合、
Layer1 に 60%
Layer2 に 100-60=40% の 75%、つまり 0.4*0.75 = 30%
背景に残りの 10%
と分配する方法ですよね。
逆に、背景から通常のアルファブレンドで計算していく場合ですが、アルファブレンドの式は
dst*(1-α) + src*α
で求められるので、背景とLayer2をアルファブレンドすると
BG*(1-0.75) + L2*0.75
となります。この結果に対して更に Layer1 をアルファブレンドすると、
(BG*(1-0.75) + L2*0.75)*(1-0.6) + L1*0.6
となります。これを計算すると、
(BG*0.25 + L2*0.75)*0.4 + L1*0.6
= BG*0.1 + L2*0.3 + L1*0.6
となって、エネルギー分配方式と全く同じ結果になります。
実際、エネルギー分配方式の式を変形していくと、後者の式
(BG*0.25 + L2*0.75)*0.4 + L1*0.6
が出てきます。
なので、背景と合成していいのであれば、背景からアルファブレンドを繰り返すだけでいいです。
# 上記のコード、多分 s と d が逆ですね。実際に式を書いてから気がつきました
ただ、
>layer のループの中でピクセルのループを回した方がいいです
の部分に関しては、dst へ書き込む回数が増えてしまうので、もう少し何か考えた方がいいかもしれませんね。
# x86 に関してだけ言えば、レジスタの数がそんなに多くないからあまり影響がなさそうな気もします
350ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(19,245ポイント)
Date: 2010/09/10(金) 18:42
No:61428
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
たろさん
まだ続きの投稿を読んでないのですが、とりあえずここだけコメント。
No:61399
> ちなみに今のコードは、こちら↓の「Photoshopでの計算方法」の文章を読んで、
> http://d.hatena.ne.jp/hajimehoshi/20080420/1208689925
> 上のレイヤーから順に透明度エネルギーを消費していく、という感じのを自分で適当に作りました。
このページは、ノベル系ゲームのキャラクター画像を自前でアンチエリアス処理する方法について書かれています。
アンチエイリアスは画像のフチがギザギザにならないように半透明処理するものです。
ゲームのキャラクター画像なので画像の殆どの部分が完全に不透明か完全に透明です。
そういう前提でないと高速化はほとんど見込めない(微妙)です。
それから半透明合成は相手方に自分方透明度の逆数を掛けるのでRGB各要素はオーバーフローしません。
Photoshopなど画像編集ソフトではレイヤー毎に合成方法を指定できます。
加算や減算などのオーバーフローやアンダーフローが発生する合成方法を指定したレイヤーがある場合、上から合成した場合と下から合成した場合では結果が異なってしまいます。
344ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(15,697ポイント)
Date: 2010/09/10(金) 22:08
No:61459
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ぬるぽんさん
わかりやすい解説ありがとうございました。理解できました。
なんというか・・言われてみると本当にその通り、気付かなかったのが悔しいです・・。
頂いたコードイメージを実装して試してみたら、期待通り動きました!
ちょっと整理して後ほど報告します。
|
|
|
|
|
Name: たろ ..上級者(15,983ポイント)
Date: 2010/09/10(金) 22:50
No:61463
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさん
> このページは、ノベル系ゲームのキャラクター画像を自前でアンチエリアス処理する方法について書かれています。
そうだったんですか。「アンチェリ」って意味不明でしたけど、アンチエイリアスのことだったのか・・。
でもすごいですね、ノベル系ゲームとか、どこでわかるんだろう・・。
> そういう前提でないと高速化はほとんど見込めない(微妙)です。
なるほど・・。ペイント系ソフトのレイヤーは確かに不透明の方が少なそうです。
うーむそこまで考えが及びませんでした。ああがんばったのに・・無念です・・。
> 加算や減算などのオーバーフローやアンダーフローが発生する合成方法を指定したレイヤーがある場合、
> 上から合成した場合と下から合成した場合では結果が異なってしまいます。
いろんな合成方式の実装も頭にはありましたが、まだ調べたりしていませんでした。
とりあえず一番基本のやつをやってみようという感じで・・。
やはりレイヤーは下から上に処理する方がよいという事でしょうか?
それとも、いろんな合成方式の実装をある程度調べてからの方がいいという感じでしょうか・・。
286ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(16,505ポイント)
Date: 2010/09/10(金) 23:23
No:61464
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
教えて頂いた案を実装してみまして、2〜3割速くなりました。
ありがとうございました。プログラムソースを添付します。
5000x5000ピクセル画像3枚を合成して確認した結果です。
(0) No:61413 の実装 → 2.88秒くらい
(1) 共用体を使ってピクセル参照の高速化 → 2.17秒くらい
元々の実装にこれ入れただけで、2割ちょっとも速くなりました。
共用体の効能をはじめて実感しました。すごい・・。
(2) ぬるぽんさんのコードイメージ → 2.05秒くらい
ほぼそのまま実装してみました。5%くらい速くなりました。
さらにコードの量がかなり減ってすっきりしました。
ソース上、#define 定義で切り替えるようになっています。
(1)と(2)の速度差がそれほどでもなかったのが少し意外でした。
コードを見ると、だいぶすっきりしているので、速そうな感じに見えたのですが・・。
ぬるぽんさんもおっしゃってますが、「dst へ書き込む回数が増えてしまう」というのが
けっこう響いているのでしょうか。dstはヒープ領域なので「ヒープを更新する回数が多い」
というのは確かに性能に影響しそうな気がします。
スタック変数に溜めておいて、まとめてヒープに書き出すとかすれば速くなるのかな・・。 
522ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(20,216ポイント)
Date: 2010/09/11(土) 02:02
No:61480
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
No:61401(No:61413)のLayerBlendUpdate関数を整理してみました。
void LayerBlendUpdate( void )
{
UINT WxH, pos;
union PIXEL32 {
UINT32 pixel;
struct {
UINT8 B,G,R,A;
};
};
PLAYER layer;
if( !LayerBlend.BIH ) return;
WxH = LayerBlend.BIH->biWidth * LayerBlend.BIH->biHeight; // 全ピクセル数
{ // 合成先のクリア
// 合成先のA要素はブレンドに使用しないのでエネルギーのバッファとして使う
union PIXEL32 *pPix = (union PIXEL32 *)LayerBlend.Bitmap;
for( pos=0; pos<WxH; pos++, ++pPix ) {
// 合成透明度エネルギー最大値で初期化(A要素)
pPix->pixel = 0xff000000;
}
}
for( layer=LayerTop; layer; layer=layer->next ) // レイヤー上から順に
{
union PIXEL32 *pSrcPix = (union PIXEL32 *)layer->Bitmap;
union PIXEL32 *pDstPix = (union PIXEL32 *)LayerBlend.Bitmap;
if( !layer->Visible ) continue; // レイヤー非表示スキップ
//if( !layer->Alpha || !pSrcPix->A ) continue; // 透明スキップ
for( pos=0; pos<WxH; pos++, ++pSrcPix, ++pDstPix ) // 先頭から1ピクセルずつ
{
UINT32 alpha = pSrcPix->A;
UINT32 energy = pDstPix->A;
UINT32 srcPixel = pSrcPix->pixel;
//if (!energy) continue; // エネルギーゼロ
//alpha = (alpha * (layer->Alpha + 1)) >> 8;
//alpha = (alpha * (energy + 1)) >> 8; // エネルギー掛ける
alpha = (alpha * (layer->Alpha + 1) * (energy + 1)) >> 16;
energy -= alpha; // エネルギー減少
pDstPix->pixel +=
((((srcPixel & 0x00ff00ff) * (alpha + 1)) >>8) & 0x00ff00ff)|
((((srcPixel & 0x0000ff00) * (alpha + 1)) >>8) & 0x0000ff00);
pDstPix->A = energy;
}
}
{ // 背景処理(最下位のレイヤーとして扱えば↑のループにまとめられる)
union PIXEL32 *pDstPix = (union PIXEL32 *)LayerBlend.Bitmap;
for( pos=0; pos<WxH; pos++, ++pDstPix ) // 先頭から1ピクセルずつ
{
UINT32 alpha = 255;
UINT32 energy = pDstPix->A;
UINT32 srcPixel = 0xffffffff; // 白背景
//if (!energy) continue; // エネルギーゼロ
alpha = (alpha * (energy + 1)) >> 8; // エネルギー掛ける
pDstPix->pixel +=
((((srcPixel & 0x00ff00ff) * (alpha + 1)) >>8) & 0x00ff00ff)|
((((srcPixel & 0x0000ff00) * (alpha + 1)) >>8) & 0x0000ff00);
pDstPix->A = 255; // 不透明
}
}
}
#完全に流れとズレてるなぁ
971ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(20,850ポイント)
Date: 2010/09/11(土) 02:39
No:61481
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
No:61464のぬるぽんさんメソッドをさらに高速化してみました。
void LayerBlendUpdate( void )
{
UINT WxH;
PLAYER layer;
union PIXEL32 {
UINT32 pixel;
struct {
UINT8 B,G,R,A;
};
};
if( !LayerBlend.BIH ) return;
WxH = LayerBlend.BIH->biWidth * LayerBlend.BIH->biHeight; // 全ピクセル数
memset( LayerBlend.Bitmap, 0xff, LayerBlend.BIH->biSizeImage ); // 合成ビットマップ背景色(白)で埋める
for( layer=LayerBottom; layer; layer=layer->up ) // レイヤー下から上に
{
union PIXEL32 *pSrcPix = (union PIXEL32 *)layer->Bitmap;
union PIXEL32 *pDstPix = (union PIXEL32 *)LayerBlend.Bitmap;
UINT n;
//if( !layer->Visible || layer->Alpha==0 ) continue; // 不可視・透明スキップ
if( !layer->Visible ) continue; // 不可視スキップ
for( n=0; n<WxH; n++, ++pSrcPix, ++pDstPix ) // 先頭から1ピクセルずつ
{
UINT32 a, ra;
UINT32 srcPixel;
UINT32 dstPixel;
union PIXEL32 tmpPix;
dstPixel = pDstPix->pixel;
srcPixel = pSrcPix->pixel;
a = (pSrcPix->A * (layer->Alpha + 1)) >>8;
ra = 255 - a;
tmpPix.pixel =
((((dstPixel & 0x00ff00ff) * (ra + 1)) >>8) & 0x00ff00ff)|
((((dstPixel & 0x0000ff00) * (ra + 1)) >>8) & 0x0000ff00);
tmpPix.pixel +=
((((srcPixel & 0x00ff00ff) * (a + 1)) >>8) & 0x00ff00ff)|
((((srcPixel & 0x0000ff00) * (a + 1)) >>8) & 0x0000ff00);
tmpPix.A = 255;
pDstPix->pixel = tmpPix.pixel; // tmpPix使わなくても変わらないみたい?
}
}
}
透明度の計算を修正しました。
前に「レイヤー間の」と言ってたときに想定してたのがこのやり方なんですよね。
--追記
この方法だと半透明合成以外の合成方法に対応するのも楽です。 
634ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(20,824ポイント)
Date: 2010/09/11(土) 03:16
No:61483
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
No:61481のコードの
ra = 255 - a;
を
ra = a ^ 0xff;
にするとちょっぴり速くなりました。
26ポイント を落としてしまった。
|
|
|
|
|
Name: ISLe ..上級者(21,146ポイント)
Date: 2010/09/11(土) 03:44
No:61486
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
#連投すみません。
GIMP2で5000x5000ピクセル画像3枚をそれぞれレイヤーに読み込んでレイヤーの透明度のスライドバーを操作すると少し遅れてある程度のブロックごとに画面が更新されていく様子が観察されました。
ブラシを走らせるとその部分は遅れることなく更新されていきます。
SAIは使ったことがないので分からないのですが、全部計算し直して一瞬でフル合成は無理ですよね。
2倍のポイントを手に入れた! 322ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(15,969ポイント)
Date: 2010/09/11(土) 15:51
No:61499
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさん実験と最適化までありがとうございます。勉強になります。
まず驚いたのですが、この struct の使い方がっ・・
union PIXEL32 {
UINT32 pixel;
struct {
UINT8 B,G,R,A;
};
};
これ、構造体名も変数名もないんですけど、オッケーなんですね。
知りませんでした。使い方はスマートになるので嬉しいです。
(1) No:61480 のコード
これ、すごく速いです。現在最速です。すごい・・。
エネルギー分配方式を使いつつ、レイヤーループの中でピクセルループをまわす、
こんなやり方があったとは・・。もはや私のコードは跡形もないですね(笑)
見た目もだいぶすっきりして・・うーむ、私のコードは境界値(0,255)のif判定が多すぎるのかな…。
(2) No:61481+No:61483 のコード
No:61464のぬるぽんさん案(私実装)と比べて、BCC551では1割ちょっと速くなりました(^^)
ただ、なぜかVC2008EEのReleaseビルドでは逆に、1割弱ですが遅くなってしまいました。
今まで常にBCCよりVCの方が速かったのですが、こんなこともあるんですね・・。
(3) 下記コード
(2) を、なんとかVCでも速くなるように改変してみました。これでなんとか・・。
でも、まだ(1)の方がわずかに速いです。
void LayerBlendUpdate( void )
{
PPIXEL32 pDstEnd;
PLAYER layer;
if( !LayerBlend.BIH ) return;
memset( LayerBlend.Bitmap, 0xff, LayerBlend.BIH->biSizeImage ); // 合成ビットマップ背景色(白)で埋める
pDstEnd = (PPIXEL32)(LayerBlend.Bitmap + LayerBlend.BIH->biSizeImage); // 合成ビットマップ最終ピクセル+1
for( layer=LayerBottom; layer; layer=layer->up ) // レイヤー下から上に
{
PPIXEL32 pSrcPix = (PPIXEL32)layer->Bitmap;
PPIXEL32 pDstPix = (PPIXEL32)LayerBlend.Bitmap;
if( !layer->Visible ) continue; // レイヤー不可視スキップ
for( ; pDstPix < pDstEnd; ++pDstPix, ++pSrcPix ) // 先頭から1ピクセルずつ
{
UINT32 a, ra;
a = (pSrcPix->A * (layer->Alpha + 1)) >>8;
ra = a ^ 0xff;
pDstPix->pixel =
(
((((pDstPix->pixel & 0x00ff00ff) * (ra + 1)) >>8) & 0x00ff00ff)|
((((pDstPix->pixel & 0x0000ff00) * (ra + 1)) >>8) & 0x0000ff00)
)
+ (
((((pSrcPix->pixel & 0x00ff00ff) * (a + 1)) >>8) & 0x00ff00ff)|
((((pSrcPix->pixel & 0x0000ff00) * (a + 1)) >>8) & 0x0000ff00)
)
| 0xff000000;
}
}
}
あの、ちなみにですが、ISLeさんに No:61325 で紹介して頂いた「テーブルを使う方式」は、
まだ登場していないですよね・・?これからちょっと考えてみようかと思ってます。
ぬるぽんさん、ISLeさん、ありがとうございました!m(_ _)m
683ポイント を落としてしまった。
|
|
|
|
|
Name: たろ ..上級者(16,825ポイント)
Date: 2010/09/11(土) 17:50
No:61514
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさん
> GIMP2で5000x5000ピクセル画像3枚をそれぞれレイヤーに読み込んでレイヤーの透明度のスライドバーを操作すると少し遅れてある程度のブロックごとに画面が更新されていく様子が観察されました。
はい、GIMP2(Windows版のGIMP2.6.6)は、私も同様の操作を試していました。
画像が上から順に処理されていく様子がわかりますね。なんかテレビの走査線が太くなったような雰囲気?
私のPCでは、スライドバーを動かし続けると、上の方のほんのちょっとだけしか処理されずに次の透明度の
処理に移ってしまい、スライドバーを止めてちょっと待たないと合成結果が見れない感じになります。
うーんこれは遅いなぁ・・などと思っていました。
> SAIは使ったことがないので分からないのですが、全部計算し直して一瞬でフル合成は無理ですよね。
すみません、「一瞬」は言い過ぎな気がしてきました・・。
SAIの挙動を再確認したところ、さすがに3000x3000くらいになるとモタつく感じがありました。
ただ、3000x3000でレイヤー3枚くらいなら、スライドバーの動きに合わせて、かろうじてほぼリアルタイムに
画像全体の処理結果が表示されて、フェードイン・フェードアウト動画を見ているような雰囲気になります。
動画の1秒あたりのコマ数でいうと、どうだろう・・秒10コマ弱くらいかな・・?
2000x2000ならモタつきはほとんど感じません。
GIMPだと、2000x2000でも、スライドバーを動かし続けたら、画像の上の方ちょっとだけしか処理されず、
次の処理になってしまいます。レイヤー枚数が増えることによる処理速度の低下も顕著な気がします・・。
と確認していたら・・よく考えると、GIMPは処理中の結果を逐一表示しているんですね・・。
これはけっこうな負荷になりそうな気もしてきた。合成処理が遅いとは言えないのかな・・。
ちなみにSAIはメモリ使用量はやけに多くて、私のPC(メモリ2GB)だと、5000x5000画像はレイヤー2枚までが
限界です・・。このメモリ使用量の多さに高速動作の秘密があるのか?などと勝手に推測してみたりしてます(^^;

2倍のポイントを手に入れた! 856ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(21,515ポイント)
Date: 2010/09/11(土) 18:55
No:61517
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
> (1) No:61480 のコード
> これ、すごく速いです。現在最速です。すごい・・。
アンチエイリアス用途前提なのでいろいろ端折っています。
実際にゲームに組み込む場合は運用レベルで工夫してもっと速くする余地があります。
半透明合成しか対応できないので画像編集ソフトでは使えないですね。
> (2) No:61481+No:61483 のコード
> No:61464のぬるぽんさん案(私実装)と比べて、BCC551では1割ちょっと速くなりました(^^)
> ただ、なぜかVC2008EEのReleaseビルドでは逆に、1割弱ですが遅くなってしまいました。
> 今まで常にBCCよりVCの方が速かったのですが、こんなこともあるんですね・・。
> (3) 下記コード
> (2) を、なんとかVCでも速くなるように改変してみました。これでなんとか・・。
> でも、まだ(1)の方がわずかに速いです。
最適化オプションを速度優先にすると変わりますかね?
こちらではオプションの影響はあまり無い感じですけど繰り返し動かしてみるとかなりバラツキがありました。
#昨晩は0xff000000をORするよりAメンバに255を代入する方が速かったのに。
このソースでは最適化はコンパイラ次第なのであんまり気にしても仕方ないですね。
> あの、ちなみにですが、ISLeさんに No:61325 で紹介して頂いた「テーブルを使う方式」は、
> まだ登場していないですよね・・?これからちょっと考えてみようかと思ってます。
半透明合成はオーバーフローしないのでテーブルを使ってないです。
加算合成や減算合成とか実装するときに「テーブルを使う方式」が役に立ちます。
ただ処理速度はもっと遅くなってしまいます。
3000x3000レイヤー3枚でそこそこついてくるというのはかなり速いですね。
レイヤー毎の透明度を事前計算したバッファを作っていたりするのかもしれません。
SAIのレイヤーの合成方法はPhotoshopやGIMP2のとはいろいろ違うみたいで、速度低下するものを避けてたりするのかも。
> と確認していたら・・よく考えると、GIMPは処理中の結果を逐一表示しているんですね・・。
> これはけっこうな負荷になりそうな気もしてきた。合成処理が遅いとは言えないのかな・・。
描画したところは即座に処理してそれ以外は操作してないときに進めるようにしているのですね。
この辺はどんなタイミングで合成処理を呼び出すかという話になります。
合成処理自体は同じコードが使えるので大丈夫ですよ。
ピクセルを差すポインタの進め方をちょっと工夫すれば一部の矩形だけを対象にできます。
369ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(17,226ポイント)
Date: 2010/09/11(土) 22:02
No:61528
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさん
> 実際にゲームに組み込む場合は運用レベルで工夫してもっと速くする余地があります。
> 半透明合成しか対応できないので画像編集ソフトでは使えないですね。
ほぇぇ・・ゲームソフトの高速化の追求はすごそうですね・・。
でも速いからもったいない気がしてます。しばらく残しておこう。
> 最適化オプションを速度優先にすると変わりますかね?
「実行速度を優先(/Ot)」をつけてみましたが、特に影響は感じられませんでした。
1.3秒と1.4秒の違いくらいです。アセンブラが読めない事もありコンパイラ任せにしてます・・。
> 半透明合成はオーバーフローしないのでテーブルを使ってないです。
> 加算合成や減算合成とか実装するときに「テーブルを使う方式」が役に立ちます。
あら、そうだったんですか。
やっぱりイマイチここら辺の話がわかってないようです・・。
他の合成方式を実装しようとした時に、今回の話の有り難さが実感できるのかなぁ。
覚えておきたいと思います。
> レイヤー毎の透明度を事前計算したバッファを作っていたりするのかもしれません。
> SAIのレイヤーの合成方法はPhotoshopやGIMP2のとはいろいろ違うみたいで、速度低下するものを避けてたりするのかも。
なるほど。この次は、そういったバッファやテーブルみたいな「メモリ消費量が増えるけど速い」
という工夫になるのかな・・。どっかの掲示板で、MMXやアセンブラもかなり使っているというのも
見たことがあります。それとの合わせ技かな。うーんちょっともうお腹いっぱいな気分・・( ̄∇ ̄;)
> ピクセルを差すポインタの進め方をちょっと工夫すれば一部の矩形だけを対象にできます。
はい、これは必要だなーと思ってました。ブラシで塗った部分だけ更新するためにも・・。
ただ、全体合成を分割処理して画面を更新しながら・・というのは、実装がゴチャゴチャしそうな事と
全体の合成にかかる時間が伸びそうで、できれば避けたいなぁと思ってしまいます。。
いろいろ教えて頂き本当にありがとうございました!
401ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(21,716ポイント)
Date: 2010/09/12(日) 02:44
No:61547
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
No:61499のコードはまだ少し速くできました。
pDstPix->pixel =
((
(((pDstPix->pixel & 0x00ff00ff) * (ra + 1)) & 0xff00ff00)|
(((pDstPix->pixel & 0x0000ff00) * (ra + 1)) & 0x00ff0000)
) + (
(((pSrcPix->pixel & 0x00ff00ff) * (a + 1)) & 0xff00ff00)|
(((pSrcPix->pixel & 0x0000ff00) * (a + 1)) & 0x00ff0000)
) >> 8)
| 0xff000000;
右シフトをまとめることができます。
201ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(17,956ポイント)
Date: 2010/09/12(日) 12:25
No:61592
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
ISLeさん
おおっ、これを入れたら、No:61480 より速くなりました!
BCCでもVC2008でも一番速いです。ついにトップ交代です(笑)
ちなみに、VC2008で警告「C4554: '>>' : 演算子の優先順位に問題があります。かっこを使用して・・」
が出たので、カッコを1組増やしました。
pDstPix->pixel =
(((
(((pDstPix->pixel & 0x00ff00ff) * (ra + 1)) & 0xff00ff00)|
(((pDstPix->pixel & 0x0000ff00) * (ra + 1)) & 0x00ff0000)
) + (
(((pSrcPix->pixel & 0x00ff00ff) * (a + 1)) & 0xff00ff00)|
(((pSrcPix->pixel & 0x0000ff00) * (a + 1)) & 0x00ff0000)
)) >> 8)
| 0xff000000;
改めて、5000x5000の3枚で、最初のNo:61401からどれくらい速くなったか確認してみました。
VC2008EEのReleaseビルド(/Ot追加)で、1.51秒台 → 1.03秒台
BCC5.5.1最適化オプション付き(※1)で、2.08秒前後 → 1.18秒台
VCで約3割、BCCで倍近く、の向上かな。コードはだいぶ短くすっきり。
ここまでのプログラム全体を添付しておきます。
ふう・・なんだかやりきった感があります(笑)
ありがとうございました!
※1
bcc32 -W -5 -O -O2 -Oc -Oi -OS -Ov LayerBlend.c
400ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(21,849ポイント)
Date: 2010/09/13(月) 01:28
No:61635
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
No:61480も最後の右シフトをまとめたら速くなりますよ?
ウインドウズのノベル系ゲームでこういったチューニングが盛んだったのはひと昔くらい前ですかね。
あらためて調べてみると最近でもけっこう需要があるみたいで不思議な感じがします。
わたしにとってもまとめができて良い機会でした。
インラインアセンブラでMMXをゴリゴリ叩いてもアプリを64ビット対応するときには使えなくなります。
これからおぼえるならマルチコアやGPGPUを活用する方向が良いかもしれません。
開発頑張ってください。
77ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(18,232ポイント)
Date: 2010/09/13(月) 06:00
No:61636
|
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
> No:61480も最後の右シフトをまとめたら速くなりますよ?
ひえ、そうですね・・見直してませんでした・・。やってみたら速くなりました。
ただ私のPCだと、まだ僅差で No:61499+No:61547 の方が速いような・・?まあでも微妙な差です。
> ウインドウズのノベル系ゲームでこういったチューニングが盛んだったのはひと昔くらい前ですかね。
> あらためて調べてみると最近でもけっこう需要があるみたいで不思議な感じがします。
> わたしにとってもまとめができて良い機会でした。
薄々そうかもなーとは思ってましたがやはり・・。10年前とかでしょうか・・。
検索で見つかるWebサイトも、昔のものが多くて、最近のものは少ないです。
需要は私にはめっちゃあります!(笑)今回のコメント履歴と出来上がったコードはかなりの貴重品です。
本当にいい勉強になりました。ありがとうございました。m(_ _)m
> インラインアセンブラでMMXをゴリゴリ叩いてもアプリを64ビット対応するときには使えなくなります。
あら・・そうなんですね・・。
> これからおぼえるならマルチコアやGPGPUを活用する方向が良いかもしれません。
GPGPU系は確かに、なんだか使わないとヤバいのか的な気配を感じてはいました。興味ありつつ、
でもよく考えたら自分のPCのグラフィックはチップセット内蔵だし、DirectX使っても特に効果なし?
と思って手が出ず・・でもそのうちやってみたいです。いいグラフィックがついた新しいPCがほしい(笑)
マルチコア活用って単純にはマルチスレッド化ですよね・・?一応、遅い関数をスレッドで並列化して、
2コアだと倍近く速くなるっぽいな〜とかやってみたりしてました。マルチスレッドなら、今回の高速化
コードとは共存できて、相乗効果になって良さそうな感触です。
> 開発頑張ってください。
ありがとうございます!!!
完成まで辿り着くかどうかわかりませんが、いけるとこまでいきます。
276ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(18,254ポイント)
Date: 2010/09/13(月) 06:08
No:61637
| 解決!
|
Title: Re:[画像処理]レイヤー合成の高速化について
|
|
一段落した気がするので、解決といたします。
コメント頂いた皆様、ありがとうございました!m(_ _)m
22ポイント を手に入れた。
|
|
|
|
Name: たまっち ..ぴよぴよ(31ポイント)
Date: 2010/09/12(日) 02:09
No:61545
|
|
Title: できるの?
|
|
このサイトのやり方でスーパーロボット大戦のような
シミュレーションRPGは作れますか?
(MAP兵器やカットイン、戦闘アニメも含める) 
31ポイント を手に入れた。
|
|
|
|
Name: パコネコ ..熟練のプログラマー(41,937ポイント)
Date: 2010/09/12(日) 08:29
No:61556
|
|
Title: Re:できるの?
|
|
カットインとかは絵などをどうにかできればできるようになるでしょうが、
戦闘とかは結構勉強しないといけないと思います。
(敵の行動とか)
このサイトのやり方というのはDXライブラリのことですか?
だとしたら、大概の事はできると思いますけど…(私レベルじゃできないこと多いけど)
作れるかはプログラマーの力次第な気がします。
(時間はかかると思いますが…)

78ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) [URL] ..ウィザード(1,274,456ポイント)
Date: 2010/09/12(日) 10:45
No:61582
|
|
Title: Re:できるの?
|
|
うちで詳しく紹介しているコードはSTGが主なので、すぐに応用できるかどうかは解りませんが、
理屈を勉強して応用することが出来れば可能だと思います。
自分が考えている仕様と完全に同じものがいつもネットにあるとは限りませんから、
作る力を付けて、自分で作るようにする方が近道だと思います。
まずは、大きなものを作るのではなく、小さなものから作ってみてください。
今どこまで学習されているか解りませんが、DXライブラリの基本機能が解ったなら、
カットンするだけ、とかマップを表示するだけ、とかモジュールの一部だけを作ってみてください。
そうしながら次第に機能を拡張していけば楽しくもあり、解りやすくもあると思います。
ただし設計にかかわる部分は経験が必要である可能性も高いので、困ったら質問して頂ければと思います。
もしガッツリゲーム制作を勉強したければ本屋さんで参考書を探したりしてみてはどうでしょう。
322ポイント を手に入れた。
|
|
|
|
|
Name: softya [URL] ..ハッカー(215,631ポイント)
Date: 2010/09/12(日) 11:36
No:61584
|
|
Title: Re:できるの?
|
|
このサイトに解説されているのは非常に基本的なアルゴリズムで、スーパーロボット大戦の様なものを作るには足らないものが沢山あります。
ただ、スーパーロボット大戦のサンプルがここ以外の何処かのサイトに落ちている訳ではなく自分で考えないといけません。それには勉強しないと行けませんので大変時間がかかります。何年かかっても作るぞ!って気持ちが無いと作り上げることは出来ませんが気持ちさえあれば作ることも夢ではないと思います。
地道に始めるつもりがあるのでしたら、この掲示板がお役に立つと思います。
そんな面倒なものは嫌だ!ってことなら無料の作成ツールもありますので検討してみてください。
臥龍公式サイト
http://kikeroga.web.fc2.com/GaRon/
305ポイント を手に入れた。
|
|
|
|
|
Name: たまっち ..ぴよぴよ(165ポイント)
Date: 2010/09/12(日) 14:40
No:61598
|
|
Title: Re:できるの?
|
|
ありがとうございました。
時間はかかりそうですができるところから
少しずつやっていきたいと思います。
それから、ドット絵を使ったゲーム
(スーパーマリオのようなもの)も作れるのですか?
2倍のポイントを手に入れた! 134ポイント を手に入れた。
|
|
|
|
|
Name: softya [URL] ..ハッカー(216,048ポイント)
Date: 2010/09/12(日) 14:54
No:61599
|
|
Title: Re:できるの?
|
|
スーパーファミコンにあったようなゲームなら作る人の技術力が十分で掛ける時間次第でなんでもできると思っていただいて結構です。
スーパーマリオワールド、タクティクス・オウガ、聖剣伝説2、FINAL FANTASY VI、ストリートファイターIIでも技術的にはDXライブラリで作れるます。製作期間やグラフィックの問題はありますが。
・テイルズ・オブ・ファンタジア
・不思議のダンジョン2 風来のシレン
・ゼルダの伝説 神々のトライフォース
・海腹川背
どれもプログラミングの技術力だけの問題です。
【追記】
補足として誰にでもここまでのものが作れるようになる訳ではありません。
なんと言うか一種のセンス(才能)が必要です。
プログラミング・センスやゲーム開発センスと言った類のものです。
こればかりは作り始めて見ないと他人にも本人にも分からないことです。
【追記の追記】
もっとも重要な才能は、バグでヘコタレないこと、プログラミングが楽しいこと、開発を楽しめることです。
これはゲームを遊ぶのが好きや遊ぶのが得意とまた別の才能です。
これさえあれば人それぞれの時間が必要ですが作れるようになっていくと思います。 
242ポイント を手に入れた。
|
|
|
|
|
Name: たまっち ..ぴよぴよ(216ポイント)
Date: 2010/09/12(日) 22:42
No:61630
| 解決!
|
Title: Re:できるの?
|
|
ありがとうございました。
まずは知識を増やすため、プログラミングの
勉強から始めたいと思います。
51ポイント を手に入れた。
|
|
|
|
|
Name: ideyan ..中級者(10,538ポイント)
Date: 2010/09/11(土) 22:01
No:61527
|
|
Title: Re:質問です
|
|
まだちゃんと見てないけど、とりあえず
>sum[loop]=sum[loop-1]+l[loop];
これ、loop=0の時まずくないですか?
後、SampleInputではうまくいっているんでしょうか?
57ポイント を手に入れた。
|
|
|
|
|
Name: pon ..入門者(4,127ポイント)
Date: 2010/09/11(土) 22:34
No:61531
|
|
Title: Re:質問です
|
|
確かにそこは何とかした方がよさそうですね。
SampleInputはうまくいっています。
42ポイント を手に入れた。
|
|
|
|
|
Name: ideyan ..中級者(10,548ポイント)
Date: 2010/09/11(土) 23:54
No:61532
|
|
Title: Re:質問です
|
|
該当箇所を
if(loop)sum[loop]=sum[loop-1]+l[loop];
else sum[loop]=l[loop];
と変更してsubmitしたらAcceptedになりましたよ。
10ポイント を手に入れた。
|
|
|
|
|
Name: ideyan ..中級者(10,653ポイント)
Date: 2010/09/12(日) 22:19
No:61629
|
|
Title: Re:質問です
|
|
sum[loop]=sum[loop-1]+l[loop];
の部分で、お手持ちの環境ではたまたま
sum[-1]に該当する場所が0だったか何かで
(連続して割りつけられていて、l[14]辺りが参照されてそう)、
偶然うまく動いていただけではないでしょうか。
105ポイント を手に入れた。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(41,558ポイント)
Date: 2010/09/12(日) 01:57
No:61544
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
で、今はろうとしたら今度は
cgi-lib.pl: Request to receive too much data: 2538312 bytes
と出ました。
どうやらデータが大きすぎるとのことでした。
たまにお張りになられている方はどうやって張っているのでしょうか?
あまり大きなゲームではないと自分では思っているのですが…
=======
ファイルには
txtデータ
アプリケーション
Incremental Linker File
Program Debug Database
Visual Studio Solution User Options
が入ってます。
何か入れる必要のないものがあったのでしょうか?
とりあえず入ってたもの一式で置いてあったので削れるものがあったら教えてほしいです。
今後のためにもお教えください。
==========
アプリケーション以外はいらないようでした…
==========
120kbまでと出てきたのでここには張れないんですね。
でもダウンロードしたことはあるので無理ではないと思います。
あれは別のサイトに張りつけたのでしょうか?
どうすればそんなことができるのですか?
もしよろしければ張り方教えてください。

87ポイント を手に入れた。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(41,853ポイント)
Date: 2010/09/12(日) 03:07
No:61549
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
なんだか無駄に4回も書き込んでしまいましたすいません。
これからが本題です。(夜だから見るのは明日でしょうけど…)
皆さんはどれくらいスコアを取れたでしょうか?
(赤文字の後コンティニュー?なしで)
私は「最高」で70でした。//<更新>76点取れました。
シューティングをやるのは苦手です…
チャージショットは使えたでしょうか?(強いとかの意味です)
ちなみに連打と長押しでは弾が変わります。
チャージが10?たまると勝手に発射されます。(仕様です)
敵にあたっても負けにはなりません…。
残機がなくなると赤い文字でスコアが出てきます。
(その後、・Xで続ける・Escで終了)
続けた場合スコアがそのままでスタートになります。
(スコアによって強さが変わりますから…残しときました。)
弾は
・連射
・3弾
・5弾
・集団
・いっぱい弾(50まで)
どの弾が使いやすかったなども気になってます。
使うボタンは十字キーとZボタンです。
たまにX。
注意///すでにバグ?は取り除きました。無視していただいていいです。
連打中に負けてしまいますと、スコアが消えてしまいます…
(ごめんなさい、タイトル画面はしょったんで…そのまま終了になっちゃう)
「一応」ですがスコアの確認画面はあったのですがそれでさえZボタンで終了だったので…
========
一応一番敵が強くなるのが、200点あたり…の予定です
そして、コンティニューを「何度も」使ってようやく1000を超えたところを見てきましたが…
アンナのよけれません…私にはよけれないレベルで…敵のHPもかなり高くなってました… 
210ポイント を手に入れた。
|
|
|
|
|
Name: ひよこ ..比類無きプログラマー(87,525ポイント)
Date: 2010/09/12(日) 08:01
No:61554
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
遊んでみました。楽しかったり意外と難しかったりで良かったです。
こういう簡単な形のシューティングもいいですね。
チャージショットっていうと自分的には巨大な弾が出る見たいな想像してました。
チャージショットはどれのことかわかりませんが自機の弾は4種類、連射、3弾、5弾、集団
(いっぱい弾は使えたかわかりません)確認できました。
私的には3弾が良かったと思います。(形もわかりやすくて、敵の弾も見やすくて)
配信の形はリリースビルドをしてゲーム名.exeと画像や音楽を一緒にzipファイルに入れれば大丈夫です。
試しにzipファイルを展開してそこでゲームが予想通りに動けばいいと思います。
33ポイント を手に入れた。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(41,859ポイント)
Date: 2010/09/12(日) 08:22
No:61555
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
>>ひよこさん
やってくれたんですね。
ありがとうございます。
いっぱい弾は多分弾を撃たなかったら見れます。
チャージの4ぐらいだったっけ…
多分発射されたらこれだ!!ってくらい弾が出るはず…
チャージショットは自動チャージ以外だと連射が打てなくなるので…
3弾は一応ほぼチャージなしで撃てるようにしました。
私も気に行ってます。
5弾はあまり撃たれなかったようで…失敗ですかね。
集団は弾の大きさをいじって近い場所に弾を集中させてダメージを多くする作戦でした。
巨大な弾と言いますと、どのようなものでしょうか?
作ってみたいです。
一発のでっかいのを撃つ形でしょうか?
レーザーみたいなのでしょうか?
ところで、得点は?
今後の難易度調整のために知りたいのですが…
==========
>>チャージショットはどれのことかわかりませんが
すいません。説明ちゃんとしてなかったかも…
上にも書きましたが、自動チャージショットにしています。
ほんとはチャージ中のエフェクトを入れるべきだったのですが、入れるの忘れてました…
一応目安で左上に数字を出しているのですが…
質問的には、下のがチャージショットですね。(連射と3弾以外)
5弾、集中、いっぱい弾がチャージショットです。
基本的に移動キーとZ以外は使いません。
(戦闘後の決定キーはX) 
6ポイント を手に入れた。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(42,057ポイント)
Date: 2010/09/12(日) 09:12
No:61561
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
>>シエルさん
すいません
でもどうすれば、消せるのでしょうか?
方法がわからなかったです。
取り合えずEsc以外では終了しないでください。
xボタン対策してないです。
さっき(深夜ぐらい?)生き残ってたのはそのせいだったんですね。
(私も消してひどい目にあった…)
アプリケーション以外を削ったせいだと思ってました。
120ポイント を手に入れた。
|
|
|
|
|
Name: シエル [URL] ..比類無きプログラマー(73,216ポイント)
Date: 2010/09/12(日) 09:20
No:61564
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
DXライブラリなので、ちょっとよく分かりませんね。
ウィンドウプロシージャを直接触っていれば余裕なんですけど。
確かProcessMessageあたりの関数がウィンドウプロシージャを制御していたので、
その辺の戻り値とかで、ループから抜けるようにするのではないでしょうか?
完全に推測ですが。
130ポイント を手に入れた。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(42,188ポイント)
Date: 2010/09/12(日) 09:29
No:61568
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
あ〜
無限ループの上と下でそれぞれ処理していたのでその関数読んでなかったっぽいです…
画面が出てないだけなら多分Escあたりで終了してくれると思うんですけど…どの状態でもEscは条件に入れてますし…
ありがとうございます。
後で関数リレクトリ?でも見に行きます。
131ポイント を手に入れた。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(42,066ポイント)
Date: 2010/09/12(日) 10:05
No:61574
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
>>Tatu
なっ。
158!!
すごい得点ですね。
私の倍ぐらい…何回も再チャレンジ繰り返してあの点数だったのに。
いっぱい弾ですか?
意外といい球かもしれませんね…
ちなみにチャージマックスがいっぱい弾なので、長押しばかりの人は見ることもない弾です。
==========
いっぱい弾は
基本的に50発発射してます。

122ポイント を落としてしまった。
|
|
|
|
|
Name: Dixq (管理人) [URL] ..ウィザード(1,273,942ポイント)
Date: 2010/09/12(日) 10:31
No:61577
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
チャージショットいいですね^^
後、同梱するファイルは実行ファイルだけでいいのでは?
実行ファイルはDebugコンパイルしてあるもののようですが、Releaseコンパイルされると良いかと思います。
ファイルバーのとこに「Debug」と書いてあると思いますが、プルダウンでReleaseにすればOKです。
その代りデバッグは出来なくなるので、その名の通りリリースする時だけ変えて下さい。
そしてtatuさんは毎回スコアがすごいですね^^;
どんなジャンルにも強いとは・・。
私は人に言えるようなスコアじゃありませんでした(笑
2倍のポイントを手に入れた! 356ポイント を手に入れた。
|
|
|
|
|
Name: へろり ..プログラマー(38,176ポイント)
Date: 2010/09/12(日) 10:41
No:61579
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
>画面が出てないだけなら多分Escあたりで終了してくれると思うんですけど…どの状態でもEscは条件に入れてますし…
フォーカスを受け取れ無いためESCの押下を検知出来ないと思いますが。
ProcessMessage()はウィンドウが閉じられた時に−1を返しますから、メインループの中でこいつの戻り値をチェックしておけば問題ないかと。
138ポイント を落としてしまった。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(42,290ポイント)
Date: 2010/09/12(日) 10:41
No:61580
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
>>Dixqさん
Release?
それにしたほうがいいのですか?
違いが少し知りたいです。
tatuさんって他のゲームでもすごいんですね…
これ(このゲーム)をもとにそのうちゲームバランスをちゃんとしたやつ(ボスつき)を作る予定なので
その時にリベンジを…
取り合えず今日の夜には解決マークつける予定ですけど…
こうしたほうがいいとか(絵とか以外で)ありましたら書いといてほしいです。
今回の結果で弾が増えるかが決まりますので…いや、弾が変わるかでした…
今のとこ5弾と集中はくず
224ポイント を手に入れた。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(42,345ポイント)
Date: 2010/09/12(日) 21:03
No:61624
|
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
倒しちゃったんですか!!
完敗です・・・
もっとむずいの考えておかなければ・・・
いつかリベンジしてやる〜
新しく追加したドデカ弾の感想もとむです。
ボスにはいっぱい弾ぐらいしか使えなかったから感想なさそう・・・
57ポイント を落としてしまった。
|
|
|
|
|
Name: パコネコ ..熟練のプログラマー(42,412ポイント)
Date: 2010/09/12(日) 21:58
No:61628
| 解決!
|
Title: Re:チャージショットの強さ?「雑談可」
|
|
一応、解決にします。
もしやってみた感想があれば書いといていただけると嬉しいです。
後は、要望。
なければいいです。
「解決」なので
========
だれにもきづかれてなさそうで怖いので、書いときます。
集弾はドデカ弾に変更しました。
これはまだわかりやすかったと思います。
次に、5弾が…斜め後ろにも攻撃する5弾へと進化してたのに…わかりずらかったですよね…。
自分でもわかりづらかったですし、
===========
それとプレイしてくださった方々、ありがとうございました。
また、難しそうなのできましたら皆さんに挑戦してもらいたいです。
(もちろんアドバイスも…)
今回の課題は、チャージショットの強さの検証だったので。
次回は円です。
円を意識して作ります。
「円」をね… 
67ポイント を手に入れた。
|
|
|
|
Name: ぬっち ..中級者(13,707ポイント)
Date: 2010/09/10(金) 21:08
No:61435
|
|
Title: STLの検索速度
|
|
お世話になっています。
タイトルとは質問内容が多少違ってしまうかもしれませんが、一番合うだろうと思われるものにしました。
リソースの管理クラスを作っていて、その実装方法でSTLのmapを使用することを考えました。
ところが、mapの検索にO(logN)かかり、その代替案としてのvectorがあり、この場合は検索にO(1)であるが、削除の仕方によっては削除していない要素にアクセスできないとのことです。
このことをネットで調べてみたところ、
http://www.c3.club.kyutech.ac.jp/gamewiki/index.php?%B9%E2%C2%AE%B2%BD#content_1_9
のようなサイトがあり、検索速度について触れられていました。
ところが、最後の「そこで描画するオブジェクトに〜」で始まる1段落がどういうことを言っているのかよくわかりませんでした。
ここのサイトの掲示板はスパム(?)で機能していないようでしたのでこちらで質問させていただくことにしました。
この段落はどのようなことを言っているのでしょうか?
リソースのポインタ自体を返して、それを用いて描画するということでしょうか?
mapでO(1)の検索速度で行えるということがいまいちよくわからなかったです。
私自身この問題についてよくわかっていませんので、場違いな質問でしたらすいません。
よろしくお願いします。
455ポイント を手に入れた。
|
|
|
|
Name: MNS ..熟練のプログラマー(40,519ポイント)
Date: 2010/09/10(金) 21:30
No:61439
|
|
Title: Re:STLの検索速度
|
|
描画するオブジェクトを毎回検索して取得するよりは、
描画するオブジェクトを記録するポインタを作っておいて、
それに描画するオブジェクトのアドレスを記録して使うほうが速いという意味です。
つまり、
void Render()
{
myMap.find("Car")->second.Render(); //O(logN)
}
よりは、
Object* p_obj = &myMap.find("Car")->second;
void Render()
{
p_obj->Render(); //O(1)
}
とするほうが速いということです。 
199ポイント を手に入れた。
|
|
|
|
|
Name: ぬっち ..中級者(13,734ポイント)
Date: 2010/09/12(日) 20:20
No:61620
| 解決!
|
Title: Re:STLの検索速度
|
|
MNSさん返信ありがとうございました。
なるほど、最初に描画対象のポインタを保持しておくということですね。
コート付きのわかりやすい返答ありがとうございます。
27ポイント を手に入れた。
|
|
|
|
Name: Shota ..ぴよぴよ(478ポイント)
Date: 2010/09/05(日) 13:44
No:60986
|
|
Title: CからPerlを実行したい
|
|
タイトルの通りです。
http://www.magicvox.net/archive/category/computer/development/2005_10221914/
このサイトに書いてあるとおりに実行してみたところ、以下のようなエラーがでました。
エラー E2303 C:\Perl\lib\CORE\win32.h 368: 型名が必要
エラー E2303 C:\Perl\lib\CORE\win32.h 369: 型名が必要
エラー E2303 C:\Perl\lib\CORE\win32.h 370: 型名が必要
エラー E2303 C:\Perl\lib\CORE\win32.h 371: 型名が必要
エラー E2293 C:\Perl\lib\CORE\win32.h 474: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 117: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 118: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 121: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 123: ) が必要
エラー E2141 C:\Perl\lib\CORE\perlio.h 124: 宣言の構文エラー
エラー E2293 C:\Perl\lib\CORE\perlio.h 125: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 218: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 231: ) が必要
エラー E2303 C:\Perl\lib\CORE\perlio.h 343: 型名が必要
エラー E2303 C:\Perl\lib\CORE\perlio.h 346: 型名が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 349: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 358: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 362: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 369: ) が必要
エラー E2293 C:\Perl\lib\CORE\perlio.h 374: ) が必要
エラー E2303 C:\Perl\lib\CORE\win32iop.h 73: 型名が必要
エラー E2303 C:\Perl\lib\CORE\win32iop.h 74: 型名が必要
エラー E2303 C:\Perl\lib\CORE\win32iop.h 77: 型名が必要
エラー E2303 C:\Perl\lib\CORE\win32iop.h 134: 型名が必要
エラー E2238 C:\Perl\lib\CORE\perl.h 2398: 'AV' の宣言が複数見つかった
エラー E2228 C:\Perl\lib\CORE\perl.h 2398: エラーあるいは警告が多すぎる
ActivePerlのヘッダファイルですが、全くいじってないのに何故このようなエラーがでるのでしょうか?
環境
OS:Windows XP
コンパイラ:bcc55
478ポイント を手に入れた。
|
|
|
|
Name: Shota ..ぴよぴよ(529ポイント)
Date: 2010/09/06(月) 20:12
No:61131
|
|
Title: Re:CからPerlを実行したい
|
|
#pragma comment(lib, "perl512.lib")
にして試してみましたが同様のエラーがでます。
43ポイント を手に入れた。
|
|
|
|
|
Name: naohiro19 ..かけだし(1,199ポイント)
Date: 2010/09/07(火) 00:07
No:61167
|
|
Title: Re:CからPerlを実行したい
|
|
borland\bcc55\Binのbcc32.cfgに
以下に変更します
デフォルトでは
-I"c:\Borland\Bcc55\include"
-L"c:\Borland\Bcc55\lib;c:\Borland\Bcc55\lib\PSDK"
となっているので
-I"c:\Borland\Bcc55\include;[COREまでのフルパス];"
-L"c:\Borland\Bcc55\lib;c:\Borland\Bcc55\lib\PSDK;[COREまでのフルパス];"
に変更します。
127ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..ぴよぴよ(615ポイント)
Date: 2010/09/07(火) 19:24
No:61231
|
|
Title: Re:CからPerlを実行したい
|
|
>>naohiro19
既に完了しています。
インクルードファイルが見つからないなどのエラーでなく、インクルードファイル自体のエラーなのです。
2倍のポイントを手に入れた! 86ポイント を手に入れた。
|
|
|
|
|
Name: ookami ..熟練のプログラマー(51,610ポイント)
Date: 2010/09/08(水) 12:17
No:61263
|
|
Title: Re:CからPerlを実行したい
|
|
あとは、まったくのカンですが、
どこかで
class {
ほにゃらら
}
↑「;」忘れ
とかないですか?
こうなったらソースをまとめてアップしてもらうのが
一番確実な気がします。
58ポイント を手に入れた。
|
|
|
|
|
Name: ookami ..熟練のプログラマー(51,765ポイント)
Date: 2010/09/08(水) 22:33
No:61312
|
|
Title: Re:CからPerlを実行したい
|
|
あ、そのリンク先の「だけ」なんですね。
うーん、解決しませんか。
> エラー E2303 C:\Perl\lib\CORE\win32.h 368: 型名が必要
↑みたいに、一見win32.hでエラーになっているようでも、
#include "win32.h" の前の行のミス(;つけ忘れとか)に引っ張られてるんじゃと思ったんですけどね…
あとは、そのperlモジュールをダウンロードする時、VC++用とBCC用が違ったなんてことは…?
100ポイント を手に入れた。
|
|
|
|
|
Name: ISLe ..上級者(18,483ポイント)
Date: 2010/09/09(木) 17:44
No:61365
|
|
Title: Re:CからPerlを実行したい
|
|
BCC55だといくつかの型(というかマクロ)が定義されないようです。
#プリプロセッサで避けられてる。
2倍のポイントを手に入れた! 80ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..ぴよぴよ(440ポイント)
Date: 2010/09/09(木) 18:58
No:61370
|
|
Title: Re:CからPerlを実行したい
|
|
つまりbccでは無理なんですねorz
VC++を入れるしか回避方法はないのでしょうか?
28ポイント を落としてしまった。
|
|
|
|
|
Name: Shota ..ぴよぴよ(976ポイント)
Date: 2010/09/09(木) 23:52
No:61391
|
|
Title: Re:CからPerlを実行したい
|
|
VC++からコンパイルしてみました。
Microsoft Visual C++ 2010を普通に起動すると操作がガタガタになるので
(RAM:248MBの環境ではストレス感じまくり)
Visual Stadio コマンドプロンプト (2010)
から実行してみました。
cl test.c /I C:\Perl\lib\CORE
Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
test.c
c:\perl\lib\core\win32.h(368) : error C2143: 構文エラー : ')' が '*' の前にあり
ません。
c:\perl\lib\core\win32.h(368) : error C2081: 'Stat_t' : 仮パラメーター リスト内
の名前が正しくありません。
c:\perl\lib\core\win32.h(368) : error C2143: 構文エラー : '{' が '*' の前にあり
ません。
・
・
・(文字数制限のためカット)
・
・
c:\perl\lib\core\win32iop.h(73) : error C2059: 構文エラー : ')'
c:\perl\lib\core\win32iop.h(74) : error C2143: 構文エラー : ')' が '*' の前にあ
りません。
c:\perl\lib\core\win32iop.h(74) : fatal error C1003: プログラム内のエラーが 100
個を超えました。コンパイルは中断されます。
これは更に酷い…。
536ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..熟練のプログラマー(59,219ポイント)
Date: 2010/09/10(金) 06:37
No:61403
|
|
Title: Re:CからPerlを実行したい
|
|
VisualC++のIDEからならコンパイルもリンクもできますね
コンパイルはWIN32と_CONSOLEを定義すればどうでしょう
cl -DWIN32 -D_CONSOLE 〜
ただ実行時エラーになりました
2倍のポイントを手に入れた! 6ポイント を手に入れた。
|
|
|
|
|
Name: へろり ..プログラマー(36,913ポイント)
Date: 2010/09/10(金) 09:38
No:61408
|
|
Title: Re:CからPerlを実行したい
|
|
BCCからどうにか出来ないかがんばってみましたが、ちょっとどうにもあきらめました。
VisualStudio .NET 2003 コンパイル・リンク・実行まで上手くいきましたよ。
空のコンソールアプリのプロジェクトを作成し、プロジェクトのプロパティからライブラリ・インクルードディレクトリを追加した以外一切の設定はいじってません。
ソースコードもNo:61299のサイトのソースのまんまです。
追記です。
プロジェクトのプロパティから見れるオプションです。
/Od /I "D:\Compiler\perl\lib\CORE" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Gm /EHsc /RTC1 /MLd /Fo"Debug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Wp64 /ZI /TP

2倍のポイントを手に入れた! 314ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..ぴよぴよ(651ポイント)
Date: 2010/09/10(金) 17:08
No:61420
|
|
Title: Re:CからPerlを実行したい
|
|
C:\Documents and Settings\Owner\My Documents\c++>cl test.c /Od /I "C:\perl\lib\C
ORE" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Gm /EHsc /RTC1 /MLd /Fo"De
bug/" /Fd"Debug/vc70.pdb" /W3 /nologo /c /Wp64 /ZI /TP
cl : コマンド ライン warning D9035 : オプション 'Wp64' の使用は現在推奨されてい
ません。今後のバージョンからは削除されます。
cl : コマンド ライン warning D9002 : 不明なオプション '/MLd' を無視します
cl : コマンド ライン warning D9028 : 簡易リビルド時のエラーです、通常のビルドに
戻します
test.c
c:\documents and settings\owner\my documents\c++\test.c : fatal error C1033: プ
ログラム データベース 'c:\documents and settings\owner\my documents\c++\debug\vc
70.pdb' を開けません。
データベースって何やねんorz
325ポイント を落としてしまった。
|
|
|
|
|
Name: Shota ..ぴよぴよ(983ポイント)
Date: 2010/09/10(金) 17:50
No:61423
|
|
Title: Re:CからPerlを実行したい
|
|
ありがとうございます。
修正してからコンパイルしてみました。
C:\Documents and Settings\Owner\My Documents\c++>cl test.c /Od /I "C:\perl\lib\C
ORE" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Gm /EHsc /RTC1 /MLd /Fo"./
" /Fd"./vc70.pdb" /W3 /nologo /c /Wp64 /ZI /TP
cl : コマンド ライン warning D9035 : オプション 'Wp64' の使用は現在推奨されてい
ません。今後のバージョンからは削除されます。
cl : コマンド ライン warning D9002 : 不明なオプション '/MLd' を無視します
test.c
c:\perl\lib\core\sys\socket.h(34) : warning C4005: 'ENOTSOCK' : マクロが再定義さ
れました。
c:\program files\microsoft visual studio 10.0\vc\include\errno.h(120) :
'ENOTSOCK' の前の定義を確認してください
ENOTSOCKが再定義されているようなんですが、どうしたらいいのでしょう…。
名前を変えるわけにもいきませんよね。。
おそらくこれさえ解決できれば実行ファイルはできそうなのですが。。
332ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..ぴよぴよ(710ポイント)
Date: 2010/09/10(金) 20:29
No:61431
|
|
Title: Re:CからPerlを実行したい
|
|
仕方が無いので、perlの実行ファイルを作成し、呼び出すことにしました。
file.exeと言うファイルに引数を渡して実行したくて、
Cのソースファイルに
system("file.exe test.txt");
と記述してコンパイルしました。
しかし、これを実行するとコマンドプロンプトに一瞬何かが表示されて消えてしまい、希望の動作をしません。
(file.exeは、渡された引数のファイルをオープンし、変換してkekka.txtに出力する)
(本当に一瞬なんでなんて表示されているかは分かりません。何度もキャプチャしようと思いましたが、タイミングが合わずキャプチャもできません。。)
file.exe単体で実行すると、kekka.txtが生成されて上手くいくのですが、Cで作ったexeから実行すると上手くいきません。
なぜでしょうか?
273ポイント を落としてしまった。
|
|
|
|
|
Name: Shota ..かけだし(1,022ポイント)
Date: 2010/09/10(金) 21:43
No:61442
|
|
Title: Re:CからPerlを実行したい
|
|
原因がわかりました。
file.exeはオープンソースのテキストエディタを改造してそこからから呼び出しているのですが、
テキストエディタを起動して即、file.exeを実行すると成功します。
しかし、ファイルのオープンやセーブをしてからfile.exeを実行すると、file.exeが見つからず失敗します。
ファイルオープンやセーブをするとカレントディレクトリが変更されるのが原因だと思われます。
そこで、カレントディレクトリを変更する方法を調べ、
system("file.exe test.txt");の文の前に、
SetCurrentDirectory(file.exeのあるディレクトリ)
と記述しました。
しかし、やはり上手くいきません。
どうしたらよいのでしょうか?
312ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(16,575ポイント)
Date: 2010/09/10(金) 23:52
No:61466
|
|
Title: Re:CからPerlを実行したい
|
|
「file.exeのあるディレクトリ」がわかっているのであれば、
system("\"ディレクトリ\\file.exe\" \"ディレクトリ\\test.txt\"");
ではダメでしょうか・・?
2倍のポイントを手に入れた! 70ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..かけだし(1,086ポイント)
Date: 2010/09/11(土) 00:07
No:61467
|
|
Title: Re:CからPerlを実行したい
|
|
絶対パスで記述しても何故か動作してくれません…。
system("C:\Documents and Settings\Owner\デスクトップ\nedit004\src\file.exe C:\Documents and Settings\Owner\デスクトップ\nedit004\src\test.txt");
64ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(16,652ポイント)
Date: 2010/09/11(土) 00:32
No:61469
|
|
Title: Re:CからPerlを実行したい
|
|
ソース上もその記述のままだとたぶんダメです。
・\ は \\ と書く
・パスに空白文字がある時は、パス全体を \" と \" で括る
でどうでしょうか。1つ前の私のコメントの記述のようにしてみてください。
77ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..かけだし(1,167ポイント)
Date: 2010/09/11(土) 19:20
No:61518
|
|
Title: Re:CからPerlを実行したい
|
|
system("\"C:\\Documents and Settings\\Owner\\デスクトップ\\nedit004\\src\\file.exe\" \"C:\\Documents and Settings\\Owner\\デスクトップ\\nedit004\\src\\test.txt\"");
としましたが、やはり認識してくれません。
81ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..かけだし(1,278ポイント)
Date: 2010/09/11(土) 21:37
No:61522
|
|
Title: Re:CからPerlを実行したい
|
|
ところで、これでもしできたとしても他に重要な問題がありました。
たろさんの
>>「file.exeのあるディレクトリ」がわかっているのであれば、
というコメントを頂きましたが、よく考えたら分からない場合もあるかもしれません。
仮にプログラムを配布したとして、ダウンロード先のフォルダが人によって違えば絶対パスもかわるわけですよね…。
111ポイント を手に入れた。
|
|
|
|
|
Name: たろ ..上級者(17,556ポイント)
Date: 2010/09/11(土) 22:18
No:61529
|
|
Title: Re:CからPerlを実行したい
|
|
あれ、ダメでしたか・・なんでだろう。
試しに、いまsystem()を実行しているついでに、
system("C:\\WINDOWS\\system32\\notepad.exe");
を書いて実行するとメモ帳が起動しますか?
※WindowsXPの場合なのでWindows7とか場所が違うかもしれません
起動するなら、あともう1つ日本語を含む適当なパス名で同じことをして問題ないかどうか。
以上の2つができるなら、原因は「file.exe か test.txt のパスが間違ってる」事だと思うのですが。
> 仮にプログラムを配布したとして、ダウンロード先のフォルダが人によって違えば絶対パスもかわるわけですよね…。
GetModuleFileName() 関数でプログラム(exe)自分自身のフルパスを取得できます。
file.exe との位置関係が分かれば file.exe のパスもわかると思います。
2倍のポイントを手に入れた! 330ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..かけだし(1,885ポイント)
Date: 2010/09/12(日) 18:47
No:61612
|
|
Title: Re:CからPerlを実行したい
|
|
アドバイスをもとに
試行錯誤していたらできました。
どこかが間違っていたようですね;;
fileには
C:\Documents and Settings\Owner\デスクトップ\nedit004\src\sample.txt
という値が入っています。
sprintf(buf,"\"C:\Documents and Settings\Owner\デスクトップ\nedit004\src\compile.exe\" %s",file);
として
system(buf);
としています。
すると確かにプログラムが起動するのですが、
perl側の受け取った引数が、
C:\Documents and Settings\Owner\デスクトップ\nedit004\src\sample.txt
となるはずなのに、
C:\Documents
となってしまいます。
何故でしょうか?
sprintf(buf,"\"C:\Documents and Settings\Owner\デスクトップ\nedit004\src\compile.exe\" %s",file);
を
sprintf(buf,"\"C:\Documents and Settings\Owner\デスクトップ\nedit004\src\compile.exe\" \"%s\"",file);
とするとコンパイルエラーになります
sprintf(buf,"\"C:\Documents and Settings\Owner\デスクトップ\nedit004\src\compile.exe\" '%s'",file);
としても、
C:\Documents
となってしまいます。
どうしたらいいでしょうか?
因みに、sprintfでbufに格納したあとに、bufの値をみてみると、確かに
"C:\Documents and Settings\Owner\デスクトップ\nedit004\src\compile.exe" C:\Documents and Settings\Owner\デスクトップ\nedit004\src\sample.txt
となっています。
607ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..かけだし(1,918ポイント)
Date: 2010/09/12(日) 19:11
No:61616
|
|
Title: Re:CからPerlを実行したい
|
|
原因がわかりました。
どうやらスペースで引数が区切られてしまっていたようです。
連結したら上手くいきました。
協力してくださったみなさま、ありがとうございました!
33ポイント を手に入れた。
|
|
|
|
|
Name: Shota ..かけだし(2,005ポイント)
Date: 2010/09/12(日) 19:35
No:61617
|
|
Title: Re:CからPerlを実行したい
|
|
最後に
sprintf(buff,"notepad ファイル名")
で変換後の内容を表示しようとしたら、ちゃんとnotepadが起動され、ファイルも開けるのですが、
一緒にコマンドプロンプトが起動してしまいます。
どうしたらコマンドプロンプトが起動しなくてすむでしょうか?
87ポイント を手に入れた。
|
|
|
|
Name: しろ ..初心者(7,082ポイント)
Date: 2010/09/12(日) 08:45
No:61557
|
|
Title: RPG戦闘シーンの制作について
|
|
RPGの戦闘シーンのみを作ってみようと思っています。
(こんな感じのものです→http://www.nicovideo.jp/watch/sm5740410)
トランプゲームのスタート画面のようなものは作ったことがあるのですが、そのときは「まほう→ファイア」「技→キック」(そのときはスタート画面なので、実際は違いますが)のようなシーケンス遷移を全部if文で制御しており、今考えればひどく見にくいプログラムだった気がします。
できればswitch文を使ってきれいに制御したいと思っているのですが、どこかに参考になるようなサイト(あるいはソース)などないでしょうか?
イメージとしては上のURLなのですが
@たたかう
A魔法
B技
C逃げる
で@とCは次の人の行動へ移る、AとBを選択した場合、同じ場所に魔法と技が並ぶ感じです。ただ、どのようにフラグを立てればいいか、うまく考えられず……
ヒントのようなものでもいただければ助かります。何とぞよろしくお願いいたします。
262ポイント を手に入れた。
|
|
|
|
Name: シエル [URL] ..比類無きプログラマー(73,086ポイント)
Date: 2010/09/12(日) 09:17
No:61562
|
|
Title: Re:RPG戦闘シーンの制作について
|
|
フラグの数字を変えればいいのではないですか?
enum TEST{
COMMAND0,
COMMAND1,
COMMAND2,
COMMAND3
};
enum TEST state;
state=GetState();
switch(state){
case COMMAND0:
case COMMAND1:
・
・
・
}
みたいに。
143ポイント を手に入れた。
|
|
|
|
|
Name: softya [URL] ..ハッカー(215,806ポイント)
Date: 2010/09/12(日) 12:33
No:61593
|
|
Title: Re:RPG戦闘シーンの制作について
|
|
簡単に書くと
switch(戦闘状態)
case 戦闘メニュー:
戦闘メニューの表示と選択処理
入力により戦闘状態を変更。
break;
case たたかう処理:
戦うの処理
break;
case 魔法メニュー:
魔法メニューの表示と選択処理
入力により戦闘状態を変更。
break;
case 魔法処理:
魔法ごとの処理
break;
:
以下略。
って感じです。
175ポイント を手に入れた。
|
|
|
|
|
Name: しろ ..初心者(7,330ポイント)
Date: 2010/09/12(日) 18:38
No:61611
| 解決!
|
Title: Re:RPG戦闘シーンの制作について
|
|
皆様ご回答ありがとうございます。
お返事が遅くなってしまい、申し訳ございません。
私もいろいろ調べたのですが、どうもC++でかかれているものがおおく、参考にできないものが多く、ここで質問させてもらいました(Cしか勉強していないので)。
たぶんただの分岐だけならなんとか書けると思うのですが、例えばあるキャラがレベルアップして使える魔法が増えた際、どのように自動的に項目を増やすか、などを考えるとなかなか難しいですよね。
皆様のご回答をもとに、いろいろ自分でもえたいと思います。
一応これで解決とさせていただきます。シエル様、うしお様、softya様、どうもありがとうございました。 
248ポイント を手に入れた。
|
|
|
|
Name: NEX ..ぴよぴよ(402ポイント)
Date: 2010/09/11(土) 00:40
No:61471
|
|
Title: オブジェクトが滑る処理
|
|
64*64の円のオブジェクトが滑るような演出をするプログラムを作っております。
※10円玉をテコピンした時のような感じ
マウスでクリックして離すと離した方向に向かって滑るところまでは作れました。
ただ慣性を表現する所で手間取っております。
初速度と減速はどの程度与えてやればよいのでしょうか?
クリックしていた時間によって初速度が変わるようにしております。
※早く離したらいっきに滑らすため
添付させて頂いたのがソースになります。
ソース内の下記で値を弄っております。
// 初速度の設定
if( Mouse.plFlg ){
Medal.Dir = (float)atan2( float(End.x-Start.x), float(End.y-Start.y));
Medal.Speed = -1 * float(touchCount/60) + 3; // ここの値
touchCount = 0;
}
// 移動処理
Medal.Px += int(sin(Medal.Dir) * Medal.Speed);
Medal.Py += int(cos(Medal.Dir) * Medal.Speed);
// 減算処理 // ここの値
if(Medal.Speed > 0) Medal.Speed -= 0.01f;
else Medal.Speed = 0;
添付したソースのまずいところを含めアドバイスを頂けないでしょうか?
402ポイント を手に入れた。
|
|
|
|
Name: NEX ..ぴよぴよ(533ポイント)
Date: 2010/09/11(土) 03:19
No:61484
|
|
Title: Re:オブジェクトが滑る処理
|
|
すいません・・・。
デバックしてみたらクリックして移動した距離も
速度に関連させないといけないですよね・・・。
どのくらいの値を入れればよいのかが全く分かりません・・・。
答えにくい質問かとは思いますが
皆さんのご意見をお聞かせ願えないでしょうか?
稀にジグザグに動くのは気のせいなのでしょうか?
ソースにまずいところがありましたらご指摘いただけないでしょうか?
131ポイント を手に入れた。
|
|
|
|
|
Name: NEX ..ぴよぴよ(749ポイント)
Date: 2010/09/11(土) 03:25
No:61485
|
|
Title: Re:オブジェクトが滑る処理
|
|
連続して投稿失礼します。
添付させて頂いたソースに
float distance = sqrt( float((End.x - Start.x) * (End.x - Start.x) + (End.y - Start.y) * (End.y - Start.y)) );という1行を追加しております。
// 初速度の設定
if( Mouse.plFlg ){
float distance = sqrt( float((End.x - Start.x) * (End.x - Start.x) + (End.y - Start.y) * (End.y - Start.y)) );
Medal.Dir = (float)atan2( float(End.x-Start.x), float(End.y-Start.y));
Medal.Speed = -1 * float(touchCount/60) + 7; // ここの値
touchCount = 0;
}
↑に記載し忘れてしまいました。
216ポイント を手に入れた。
|
|
|
|
|
Name: NEX ..かけだし(1,353ポイント)
Date: 2010/09/11(土) 06:14
No:61489
|
|
Title: Re:オブジェクトが滑る処理
|
|
何度もすみません・・・。
質問させて頂いてから修正を重ね
少しだけ慣性?がかかったように見えるようになりました。
一番最初に添付させて頂いたソースのLoop内がかなり変わっております。
ただ問題が御座いまして「く」の字の様にマウスを動かしてしまうと
とんでもない方向に円が飛んで行ってしまいます。
参考になりそうなURLを探していたらこのような動作のことをフリックというのですね・・・。
http://hoshiba.seesaa.net/article/121780114.html
URLはiphoneですがこのようなことがやりたいです。
void Loop(){
// タッチされている時間をカウント
if( Mouse.lFlg ) touchCount++;
// 触っている時
if( Mouse.lFlg ){
Medal.Px = (float)Mouse.x;
Medal.Py = (float)Mouse.y;
}
// 座標計算
if( Mouse.clFlg ){
Start.x = Mouse.x;
Start.y = Mouse.y;
}
if( Mouse.plFlg ){
End.x = Mouse.x;
End.y = Mouse.y;
}
// 移動
// 角度を修正
// float rot = float(Medal.Dir/180*M_PI);
// 初速度の設定
static float distance = 0.0f;
if( Mouse.plFlg ){
float distance = sqrt( float((End.x - Start.x) * (End.x - Start.x) + (End.y - Start.y) * (End.y - Start.y)) );
if( distance>= 5){
Medal.Dir = (float)atan2( float(End.x-Start.x), float(End.y-Start.y));
Medal.Speed = -1 * float(touchCount/60) + 7; // ここの値
touchCount = 0;
}
}
// 移動処理
Medal.Px += int(sin(Medal.Dir) * Medal.Speed);
Medal.Py += int(cos(Medal.Dir) * Medal.Speed);
// 減算処理 // ここの値
if(Medal.Speed > 0) Medal.Speed -= (-0.01f * distance) + 0.2f;
else Medal.Speed = 0;
if( Key[KEY_INPUT_F2].trgKey ) Init();
}
604ポイント を手に入れた。
|
|
|
|
|
Name: NEX ..かけだし(1,260ポイント)
Date: 2010/09/12(日) 17:23
No:61610
| 解決!
|
Title: Re:オブジェクトが滑る処理
|
|
Justy様
ソースまでありがとうございます。
なんとか出来ました。
マウスの座標取得の方法を変えて古いフレームと見比べれば実装できるのですね。
勉強になりました。ありがとうございました。
93ポイント を落としてしまった。
|
|
|
|
Name: K・山田 ..ぴよぴよ(161ポイント)
Date: 2010/09/12(日) 00:47
No:61536
|
|
Title: 無題
|
|
初めまして、K・山田と申します。
龍神録プログラミングの館 を全てやって非常にタメになりました、ありがとうございます。
ここで終わるのもアレなので、まずは新しくステージを追加していきたいと思っております。
過去ログを見た結果、switch文を使うのがいいとは書かれていましたが他の方法はありませんでしょうか?
どこかで管理者様がステージの作り方を書いた構文をどなたかにメールで送っていたのも気になりました。
よろしければ私にその構文を書いたメールを頂ければ幸いです、図々しくて申し訳ありません。
私なりに考えた結果で、こういう感じで作る事は可能でしょうか?
ステージ1開始
↓
ボスを倒す
↓
画面を黒くしたりしてその間にリザルト等を出したりする
↓
リザルト等を出している間に背景を次のステージ用に切り替える
↓
リザルトを解除後、あたかも次の面に変わったかのように変わる
というのは不可能でしょうか?
擬似的に黒くしている間に背景だけを切り替える〜 という方法です。
csvファイルを調整すれば敵の調整とかは出来そうです。
161ポイント を手に入れた。
|
|
|
|
Name: Dixq (管理人) [URL] ..ウィザード(1,274,134ポイント)
Date: 2010/09/12(日) 10:38
No:61578
|
|
Title: Re:ステージの追加について
|
|
基本機能は出来ているので、初期化関数の中身だけ変えれば2面としても動作するように思います。
私なら、まず、設定値をスクリプトから操作出来るように変更します。
ボスの体力・弾幕の出る順番など、スクリプトで設定出来るようにします。
現在関数ポインタで弾幕の出る順番を管理しているので、まず配列に関数ポインタを入れて置き、
スクリプトからはその要素番号を指定するように私ならします。
スクリプトというと難しそうですが、値はテキストファイルでも何でも構いません。
要は実行ファイルをコンパイルしなおさなくてもゲーム内容が変更できれば良いのです。
ステージごとに依存しているパラメータを全て変更できるようにしたら、
後はIni関数をいじるだけか、もし必要があったとしても少し修正すればいいだけかと思います。
自機の残数やスコアなど、初期化関数で2面以降はスキップしないといけない要素もありますから、
その辺注意して初期化する必要があるように思います。
後、メールの件は忘れましたが・・いつ頃の話でしょう?
192ポイント を手に入れた。
|
|
|
|
|
Name: K・山田 ..かけだし(1,323ポイント)
Date: 2010/09/12(日) 15:34
No:61602
|
|
Title: Re:ステージの追加について
|
|
さっそくのお返事ありがとうございます。
シエル 様>
なるほどありがとうございます、当面はその方向で検討したいと思っております。
Dixg 様>
なるほど…スクリプトを使って根本的な部分はあまり変えずに対応出来るという事ですね。
Excelファイルのcsvと同じようなシステムでしょうか、調べて試してみたいと思います。
そこをいじって不可能ならば別の所を修正すると……。
メールの件は過去ログの
Name: 管理人 [URL] ..伝説のハッカー(509,029ポイント) Date: 2008/02/07(木) 13:38 No:14099
Title: Re:ステージの作り方。
回答はメールの方がいいのでしょうか??
一応両方にお書きしますが、よければ掲示板の方にご返答下さい。
>管理人さんのサンプルソースだと敵の出現パターンや出現のタイミングはcase文による記述で書かれていたのですがあの方法で四聖龍神録(体験版)も作ったのでしょか?
はい、全く違います・・・。
というか、全体のソースコード丸ごと違います(汗
というのも、作った当時、あのシューティングの館は、ここまで多くの人に見ていただけると思っておらず、
また、小さなミニゲームを想定していたのと、知り合いが「効率いいプログラムより、見慣れた書き方で書いてほしい」と言っていたのを受けて、
最適な書き方より、とにかく難しくないコードで書こうとして出来たものです。
なので、本来の効率的なかき方とは全然違うのです。
そのせいで、色々な人から質問が来てしまい、私のせいで、いろんな人を混乱させてしまったようです・・;
シューティングの館は近々削除予定です。
龍神録が完成したらシューティングの館をもっときちんとしたコードに書き直す予定です。
敵は数百〜数千も出てくるので、case文で書いているととんでもないことになりますし、拡張性も汎用性もありませんし、
修正も困難ですよね。
私は、一般的にどのようにするかは存じませんし、シューティングプログラムの本などを読んだこともありません。
>>私が我流でやっている方法ですが、エクセルでデータを書いています。
>>例えば私が作っているゲームのステージ2では、添付ファイルのようになっています。
>>ファイルを添付したので、よければご覧下さい。
>>(添付は下の投稿にやり直しました。)
ここの部分が気になりました、お手数かけます。
2倍のポイントを手に入れた! 1,142ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) [URL] ..ウィザード(1,274,641ポイント)
Date: 2010/09/12(日) 15:55
No:61604
|
|
Title: Re:ステージの追加について
|
|
これはシューティングの館の質問だったと思います。
龍神録プログラミングの館の他にシューティングの館があり、そちらの質問かと思います。
> ステージ1開始
> ↓
> ボスを倒す
> ↓
> 画面を黒くしたりしてその間にリザルト等を出したりする
> ↓
> リザルト等を出している間に背景を次のステージ用に切り替える
> ↓
> リザルトを解除後、あたかも次の面に変わったかのように変わる
について、もちろん可能だと思いますが、詳細の仕様はどんなものでしょう?
> 擬似的に黒くしている間に背景だけを切り替える〜 という方法です。
の「擬似的」は何を意味しますか?
背景が一度全く見えない状態にしてよく、キャラが一瞬止まるような事があっても良いなら直ぐに出来ると思います。
黒で塗りつぶしている間に読み込んで必要な画像を読み込み直せばよいだけですから。
もしそうではなく、クロスワイプするように、ジワッと1面と2面がまざるような仕様だとグッと難易度は上がるでしょう。
同時に2種類の背景描画処理をするにはそれを管理するモジュールも必要になりそうです。
また、ロードしていないように思わせるには、面の終わりに近づいたら裏でゲームと並行して読み込みを開始するような仕組みも必要でしょう。
DXライブラリはマルチスレッドに対応していませんから、同時に処理をする時は工夫が必要だと思います。
背景の画像の大きさにもよりますが、小さければそのような仕組みを考えなくても一瞬で読み込めるかもしれませんね。
ただ、もしまだ2面が出来ていないなら、仕様にこだわるより先に2面を作ってしまい、それから検討した方が良いと思います。
185ポイント を手に入れた。
|
|
|
|
Name: zman ..ぴよぴよ(677ポイント)
Date: 2010/09/11(土) 17:01
No:61510
|
|
Title: 無題
|
|
たアスタリスクで作成した直角三角形 を印字するプログラムを関数を使って作り直してみよう。指定された文字を指定 された回数だけ連続して印字する処理を関数化する。この関数の宣言を
int run(char c, int length);
とする。すなわち、関数runは文字cを長さlengthだけ印字する。 戻り値は印字した文字の個数(すなわち、length)とする。
この関数runを作成し、キーボードより入力された任意の正の整数を高さと する直角三角形を印字するプログラムを作成せよ。
% decWithFunc
正の整数: 15
1: ***************
2: **************
3: *************
4: ************
5: ***********
6: **********
7: *********
8: ********
9: *******
10: ******
11: *****
12: ****
13: ***
14: **
15: *
%
というもんだいで、自分が書いたソースをコンパイルすると
『引数1個の'run'を渡しますにより、キャストなしで整数からポインタを作りました』
とエラーが出ます。これはどういう意味で、どう直せばよいでしょうか?下が私が書いたソースです。
#include<stdio.h>
# define BUFFER_SIZE (256)
int get_int(void)
{
char buf[BUFFER_SIZE];
fgets(buf, BUFFER_SIZE, stdin);
return atoi(buf);
}
//プロトタイプ宣言
int run(char mark,int length){
int j;
for(j=0 ;j < length ;j++){
printf("%c",mark);
}
printf("\n");
return length;
}
int main(void){
int number,i;
printf("数字を入力せよ: ");
number = get_int();
if(number > 0){
for(i=0 ; i < number ; i++){
printf("%d:",i+1);
//空らん
run(" ",i+1 );
//*
run("*",number-i);
}
}
return 0;
}
677ポイント を手に入れた。
|
|
|
|
Name: へろり ..プログラマー(37,926ポイント)
Date: 2010/09/11(土) 17:19
No:61511
|
|
Title: Re:無題
|
|
というより、
>正の整数: 15
> 1: ***************
> 2: **************
> 3: *************
> 4: ************
> 5: ***********
> 6: **********
> 7: *********
> 8: ********
> 9: *******
> 10: ******
> 11: *****
> 12: ****
> 13: ***
> 14: **
> 15: *
> %
というのは正解例でしょうか。
□
□□
□□□
で直角ですから、直角であるなら、
**
*
ではなく、
***
*
とならなければならない気がするのですが。
件の出力が仕様と考えてよろしいのでしょうか?
62ポイント を手に入れた。
|
|
|
|
|
Name: fatens ..上級者(18,553ポイント)
Date: 2010/09/11(土) 18:44
No:61516
|
|
Title: Re:無題
|
|
>printf("\n");
run関数内で改行してしまうと思ったような出力結果にならないので削除。
>printf("%d:",i+1);
ずれないようにするため%2dに。
>run(" ",i+1 );
>run("*",number-i);
run関数に渡すのは文字列ではなく文字なので' 'で囲みます。
また、上で消したprintf("\n");をこのループの最後にもってきます。
179ポイント を手に入れた。
|
|
|
|
|
Name: zman ..ぴよぴよ(707ポイント)
Date: 2010/09/12(日) 13:36
No:61596
|
|
Title: Re:無題
|
|
printf("\n");の場所を変えて" "を' 'で囲むとうまくいきました。ありがとうございます。
30ポイント を手に入れた。
|
|
|
|
Name: シエル [URL] ..比類無きプログラマー(75,814ポイント)
Date: 2010/09/12(日) 12:15
No:61590
|
|
Title: 【DirectXプログラミング】シェーダを使った描画について
|
|
いつもお世話になります。
今回はシェーダを使った描画について質問があります。
色々なDirectXの入門サイトや書籍を見たのですが、シェーダを使った描画では
D3DデバイスのDrawPrimitiveメソッドを使って描画をしているものしかありませんでした。
そこで、D3DデバイスのDrawPrimitiveUPメソッドを使った場合のシェーダの描画の方法を
知りたくて質問させていただきました。
まず、下記のソースは通常の頂点バッファを作成し、DrawPrimitiveメソッドで描画している
ソースです。
当然頂点バッファを使っているので、SetStreamSourceで頂点データを渡してから描画をしています。
=====================================描画部分のコード=========================================
// 頂点のフォーマット宣言
D3DVERTEXELEMENT9 m_vertexElements[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{1, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
D3DDECL_END()
};
pD3DDevice->CreateVertexDeclaration(m_vertexElements, &m_pVertexDecl);
// オブジェクトの頂点バッファを生成
if( FAILED( pD3DDevice->CreateVertexBuffer( 4*sizeof(MY_VERTEX_POS),
D3DUSAGE_WRITEONLY,
0,
D3DPOOL_MANAGED, &m_pVB_POS, NULL ))){
return E_FAIL;
}
//頂点バッファの中身を埋める
MY_VERTEX_POS* v0;
m_pVB_POS->Lock( 0, 0, (void**)&v0, 0 );
// 各頂点の位置
v0[0].p = D3DXVECTOR3(-1.0f, 1.0f, 0.0f );
v0[1].p = D3DXVECTOR3( 1.0f, 1.0f, 0.0f );
v0[2].p = D3DXVECTOR3(-1.0f, -1.0f, 0.0f );
v0[3].p = D3DXVECTOR3( 1.0f, -1.0f, 0.0f );
m_pVB_POS->Unlock();
// オブジェクトの頂点バッファ(テクスチャ座標)を生成
if( FAILED( pD3DDevice->CreateVertexBuffer( 4*sizeof(MY_VERTEX_TEX),D3DUSAGE_WRITEONLY,0,D3DPOOL_MANAGED, &m_pVB_TEX, NULL ))){
return E_FAIL;
}
//頂点バッファの中身を埋める
MY_VERTEX_TEX* v1;
m_pVB_TEX->Lock( 0, 0, (void**)&v1, 0 );
// 各頂点のテクスチャ座標
v1[0].tex = D3DXVECTOR2( 0.0, 0.0f);
v1[1].tex = D3DXVECTOR2( 1.0f, 0.0f);
v1[2].tex = D3DXVECTOR2( 0.0f, 1.0f);
v1[3].tex = D3DXVECTOR2( 1.0f, 1.0f);
m_pVB_TEX->Unlock();
D3DXCreateEffectFromFile(pD3DDevice, TEXT("test.fx"), 0, 0, D3DXSHADER_DEBUG, 0, &m_pFX, &errors);
if( errors){
return E_FAIL;
}
// シェーダプログラムへテクニックへのハンドルの取得
m_hTech = m_pFX->GetTechniqueByName("BasicTech");
// シェーダープログラムのグローバル変数のハンドルの取得
m_hWvp = m_pFX->GetParameterByName(0, "wvp");
m_hColor = m_pFX->GetParameterByName(0, "color");
m_hTexture = m_pFX->GetParameterByName(0, "texh");
// テクスチャ画像の読み込み
D3DXCreateTextureFromFile(pD3DDevice, TEXT("tex.bmp"), &m_pTexture);
// 頂点のデクラレーションの設定
pD3DDevice->SetVertexDeclaration(m_pVertexDecl);
// ストリームとして頂点バッファを設定
pD3DDevice->SetStreamSource( 0, m_pVB_POS, 0, sizeof(MY_VERTEX_POS) );
pD3DDevice->SetStreamSource( 1, m_pVB_TEX, 0, sizeof(MY_VERTEX_TEX) );
// 色を設定→白
D3DXVECTOR4 tmpColor;
tmpColor.x = 1.0f;
tmpColor.y = 1.0f;
tmpColor.z = 1.0f;
tmpColor.w = 1.0f;
// テクニックの設定(シェーダプログラムの設定)
m_pFX->SetTechnique(m_hTech);
// シェーダーのグローバル変数の値の設定
m_pFX->SetMatrix(m_hWvp, &(m_view*m_proj));
m_pFX->SetVector(m_hColor, &tmpColor);
m_pFX->SetTexture(m_hTexture, m_pTexture);
m_pFX->CommitChanges();
// シェーダプログラムの開始宣言
m_pFX->Begin(0, 0);
m_pFX->BeginPass(0);
// 三角形の描画処理
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2);
// シェーダプログラムの終了宣言
m_pFX->EndPass();
m_pFX->End();
}
================================================ココまで========================================
ですが、DrawPrimitiveUPメソッドでは、そのメソッドの引数に頂点データの配列の先頭ポインタを渡して
描画しているので、SetStreamSourceは使いません。
そうなると、DrawPrimitiveUPの時はSetVectorやSetTextureなどでデータをGPUに渡すタイミングはいつなのかや呼ぶ必要はあるのかなどが具体的にわかりません。
頂点データの配列にディフューズ色などを含める場合などや、もしそうした場合シェーダー側(HLSL)の
プログラムはどうなるのかなどもよく分かりません。
どなたか、上記のソースをDrawPrimitiveUP用の置き換えて説明してくださる方がいらっしゃれば、
ご説明願います。
シェーダを使った描画でDrawPrimitiveUPを使った参考サイトがあれば、そのURLを貼っていただくだけでも
構いません。
よろしくお願い致します。
下記にHLSL(シェーダ)のコードも貼っておきます。
===================================ココから下はHLSLのコード============================
float4x4 wvp;
float4 color;
texture texh;
sampler TextureSampler =
sampler_state
{
Texture = <texh>;
};
void BasicVS(float3 pos : POSITION,
float2 tex : TEXCOORD0,
out float4 outpos : POSITION,
out float4 vcol : COLOR0,
out float2 outtex : TEXCOORD0)
{
outpos=mul(float4(pos,1.0f),wvp);
vcol = color;
outtex=tex;
}
void BasicPS(float4 ptex : TEXCOORD0,
out float4 outcolor : COLOR0)
{
outcolor = tex2D(TextureSampler,ptex);
}
technique BasicTech
{
pass P0
{
vertexshader = compile vs_3_0 BasicVS();
pixelshader = compile ps_3_0 BasicPS();
}
}
=========================================================================
2,530ポイント を手に入れた。
|
|
|
|
Name: シエル [URL] ..比類無きプログラマー(75,969ポイント)
Date: 2010/09/12(日) 12:58
No:61594
| 解決!
|
Title: Re:【DirectXプログラミング】シェーダを使った描画について
|
|
すいません。質問しといて何ですが、シェーダーを使った描画では頂点ストリームを扱える数などもあり
DrawPrimitiveを使うのが一般的なようですので、DrawPrimitive一本で行きたいと思います。
どうもありがとうございました。
※もしDrawPrimitiveUPの方法をご存知の方がいれば、回答していただいて構いません。というか嬉しいですw
155ポイント を手に入れた。
|
|
|
|
Name: 青3号 ..ぴよぴよ(195ポイント)
Date: 2010/09/12(日) 00:34
No:61534
|
|
Title: 文字の取得と判別について(><;)
|
|
C言語で、
テキストファイルからテキストモードで文字を2文字分読み込んで、
その文字が"p"かつ"i"であるかどうかの判別をしたいのですが、
以下のコードだとコンパイラさんに
char*型はchar型に変換できない、と怒られたのです。
どうしたら文字の判別ができますか?教えてください。
なるべくバイナリではなくテキストモードでchar型の配列str[2]に
読み込んだものを使用したいのですが...
str[]がもしint型配列だったらアスキーコードの10進表を使えばできますか?
(追伸)あと、テキストモードで一行ずつ読むfgetsだと、
改行の識別ができますが、fgetcだとできないのでしょうか?
char str[2];
fgets(str,2+1, fp);
if((str[0]=="p")&&(str[1]="i"))
{
〜処理〜
}
195ポイント を手に入れた。
|
|
|
|
Name: パコネコ ..熟練のプログラマー(41,341ポイント)
Date: 2010/09/12(日) 00:41
No:61535
|
|
Title: Re:文字の取得と判別について(><;)
|
|
関係なかったらすいません
=="p"
ではなく
=='p'
ではないでしょうか?
=========
ついでに
iのほうが「==」ではなく「=」になってます。 
34ポイント を落としてしまった。
|
|
|
|
|
Name: フリオ ..プログラマー(37,273ポイント)
Date: 2010/09/12(日) 00:54
No:61539
|
|
Title: Re:文字の取得と判別について(><;)
|
|
char str[2];
に対して、
fgets(str, 2 + 1, fp);
はだめです。
>(追伸)あと、テキストモードで一行ずつ読むfgetsだと、
>改行の識別ができますが、fgetcだとできないのでしょうか?
何故、"出来ない"と考えたのでしょうか。

33ポイント を手に入れた。
|
|
|
|
|
Name: 青3号 ..ぴよぴよ(666ポイント)
Date: 2010/09/12(日) 01:46
No:61543
|
|
Title: Re:文字の取得と判別について(><;)
|
|
>パコネコさん
そうでした、シングルで囲むんでした。
=の方は私の誤記入です。
ありがとうございます。
>フリオさん
2文字読みたいなら,
単純に fgets(str,2, fp); でよいのですね?
何か勘違いしていたようです。
>何故、"出来ない"と考えたのでしょうか。
ん〜、あるマニュアルを見ただけなんですが、fgetcについて、
ストリーム から次の一文字を取ってきて返す。
ファイルの終端に達していたり、
エラーが発生している場合にはEOFを返す。
とありました。終端はあるのに改行は書いてないので、
どうやって改行を識別するのかなと・・・。
fgetsの方なら一行読んで配列に渡せばnullがつくから便利ですが...。
テキストファイルで改行をバイナリでみると0D0Aが入っていますが、
終端には0D0Aが見あたらなかったので、
改行と終端は何か別な仕組みでできていて、別の処理が必要だと思ったのですが、
いちいちfgetcで0D0Aがあるかどうか調べる必要があるのですか...。
あとイマイチEOFとNULLと\0と0D0Aの違いと仕組が理解できてません。
471ポイント を手に入れた。
|
|
|
|
|
Name: fatens ..上級者(18,984ポイント)
Date: 2010/09/12(日) 02:34
No:61546
|
|
Title: Re:文字の取得と判別について(><;)
|
|
>2文字読みたいなら,単純に fgets(str,2, fp); でよいのですね?
そういう意味ではなく、
fgets関数は最大で第2引数に指定した数-1の文字列を読み取ります。
改行またはEOFで読み取りを終了し、その改行文字を格納して、最後にナル文字('\0')を格納します。
char str[2]; に対してfgets関数で2文字読み込む際、改行文字がなかったとしてもナル文字の分がありません。
strの要素数は余裕を持っておく必要があるということです。
>終端はあるのに改行は書いてないので、どうやって改行を識別するのかなと・・・。
識別というのが何を意味しているのかよくわかりませんが、
fgetc関数の返却値を調べれば良いのではないでしょうか。
>あとイマイチEOFとNULLと\0と0D0Aの違いと仕組が理解できてません。
EOFはファイルの終端(End Of File)の略です。
NULLは何も指していない特別なポインタを意味します。
\0というか'\0'は文字列の終端を表します。
0D0AはWindows環境のテキストファイルの改行文字のアスキーコードです。
431ポイント を手に入れた。
|
|
|
|
|
Name: アビゲイル ..ぴよぴよ(669ポイント)
Date: 2010/09/12(日) 12:00
No:61588
|
|
Title: Re:文字の取得と判別について(><;)
|
|
EOFは不思議で自分も調べたことがありますね。
例えば、200byteのファイルがあるとすると、次のbyteの201byte目が暗黙のルールとしてEOFになります。
決まりごとなので、実際にEOF分として1byte使用しているわけではありません。
つまり、201byte目(最大サイズを超えた所)にアクセスした時、OSが返す値がEOFということです。
エラーの一種です。
fgetsはただのfgetcのラッパーですね。
※実装者によって実装は異なってきます。
一部抜粋) ANSI C言語辞典
for(; n>1; n--)
{
int c=fgetc(stream); /* 1文字入力 */
if(c==EOF)break;
*s=c; /* 配列に代入 */
s++; /* sを進める */
if(c=='\n')break;
}
~
*s = '\0';
187ポイント を手に入れた。
|
|
|
|
|