クラスについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
奥兵

クラスについて

#1

投稿記事 by 奥兵 » 13年前

クラスについて質問です。

下のコードは現在制作しているゲームのメイン部分なのですが、
これをクラスにしようと思い、新しく作ったクラスにコピペで移植し、同じ機能になるようにクラスを作りました。
ところが走らせてみると元のコードでは成功していた画像の読み込みが上手く行っていません。
インスタンスの確保の仕方が怪しいと考え、思いつく限りのことは試したのですが解決の糸口が見えません。
どうかアドバイスをお願いします。

↓正常に動いていたゲーム部分の元のメイン関数
unitクラスのコンストラクタで画像を読み込んでいます。

コード:

int oGameMain(class Graphic *app){//だんだんややこしくなってきたのでそのうちクラス化
	
	static int mode=INITIAL;
	static unit *hoge=NULL;
	static Eunit *enemy=NULL;

	GameMain *Gmain=NULL;/////////////////////////////////////
	static int lock=0;
	for(;app->RunMessageLoop();){	
		switch (mode){
		case INITIAL:{
			//unit hoge(app);
			hoge = new unit(app);//hogeは流石にそのうち直そう
			enemy= new Eunit(app,10,10,100,1);
			if(lock==0){
				lock=1;
				Gmain= new GameMain(app);////////////////////////////////
			}
	 //Gmain->Main(app);/////////////////////////////////////
	 
			mode = MAIN;
		}
		break;
		case MAIN:
			hoge->GetKey();//キー入力
			hoge->Blt->move();//弾の移動
			hoge->Blt->locker=hoge->Blt->locker+1;//弾の発射間隔処理

			enemy->move();//敵の移動
			enemy->hantei(*hoge->Blt); //敵の被弾判定


			/**************描画部**************/
			app->Bpaint();

			app->ClearScreen();
			if((hoge->HP)>0){
				app->paint(hoge->Graphic, hoge->x,hoge->y);//自機
			}
			if((enemy->HP)>0){
				app->paint(enemy->Graphic,enemy->x,enemy->y);
			}
			for(int i=0;i<(hoge->Blt->BltLimit);i++){//メインショット
				if((hoge->Blt->bltpos[i].flug)==1){
					app->paint(hoge->Blt->Graphic,hoge->Blt->bltpos[i].x,hoge->Blt->bltpos[i].y);
				}
			}
			 
			
			app->Epaint(); 
			/*********************************/
			//wait();
			Gmain->wait();
			Gmain->FPScheck();
			//mode=END;//仮置き
		break;
		case END:	 
			return 0;
		break;
		}
			 
	 }
	return 0;
}

↓制作したクラス

コード:

class GameMain{
public:

	enum state{
		INITIAL,
		MAIN,
		END
	};

	int mode;
	int counter;
	unit *hoge;
	Eunit enemy;
	
	int Main(class Graphic *app);
	int FPScheck();
	int wait();
	 
	GameMain(class Graphic *app);

};

GameMain::GameMain(class Graphic *app):mode(0){//oGmaeMainからの移植途中
	 
	hoge = new unit(app);
	//enemy= * new Eunit(app,10,10,100,1);
}

int GameMain::Main(Graphic *app){

	static int mode=INITIAL;
	//static GameMain *Gmain=NULL;

	for(;app->RunMessageLoop();){	
		switch (mode){
		case INITIAL:{
			unit hoge(app);
			//Gmain= new GameMain(app);

			mode = MAIN;
		}
		break;
		case MAIN:
			hoge->GetKey();//キー入力
			hoge->Blt->move();//弾の移動
			hoge->Blt->locker=hoge->Blt->locker+1;//弾の発射間隔処理

			enemy.move();//敵の移動
			enemy.hantei(*hoge->Blt); //敵の被弾判定


			/**************描画部**************/
			app->Bpaint();

			app->ClearScreen();
			//if((hoge.HP)>0){
			//hoge->Graphic;
			//hoge.Graphic;
			//app->paint(hoge->Graphic, hoge->x,hoge->y);//自機
			//}
			//if((enemy.HP)>0){
			//	app->paint(enemy.Graphic,enemy.x,enemy.y);
			//}
			//for(int i=0;i<(hoge.Blt->BltLimit);i++){//メインショット
			//	if((hoge.Blt->bltpos[i].flug)==1){
			//		app->paint(hoge.Blt->Graphic,hoge.Blt->bltpos[i].x,hoge.Blt->bltpos[i].y);
			//	}
			//}
			 
			
			app->Epaint(); 
			/*********************************/
			//wait();
			wait();
			FPScheck();
			//mode=END;//仮置き
		break;
		case END:	 
			return 0;
		break;
		}
			 
	 }
	return 0;
	
}

トントン
記事: 100
登録日時: 15年前

Re: クラスについて

#2

投稿記事 by トントン » 13年前

適当に聞きます。
制作したクラスのコメントアウトを外すとどうなりますか?

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: クラスについて

#3

投稿記事 by ISLe » 13年前

37行目でunitクラスの一時変数を宣言してますが、これが影響しているとか?
unitクラスできちんとマルチインスタンスを考慮していれば問題ないはずですが。

あるいはGameMainクラスのコンストラクタが呼ばれるタイミングの問題でしょうかね。

どちらにしても提示されたコードだけでは特定できません。

奥兵

Re: クラスについて

#4

投稿記事 by 奥兵 » 13年前

トントン さんが書きました:適当に聞きます。
制作したクラスのコメントアウトを外すとどうなりますか?
コンパイルは通るのですが、exeは動作を停止しました。 とでてプログラムが停止します。
確認してみるとどうも画像を読めていないらしく変数の中身が不正な値になっています。

奥兵

Re: クラスについて

#5

投稿記事 by 奥兵 » 13年前

ためしに動いていたoGameMainの内容に改変を加えずにGameMainクラスのMain関数に移植してみたところ、正常に動作しました。
しかしその状態で関数で宣言しているunitクラスのインスタンスをGameMainクラスのメンバとして確保しようとすると、どう書いてもexeが停止してしまいます。

↓unitクラス。コンストラクタで画像をロードさせています。

コード:

class unit {
public:

	ID2D1Bitmap *Graphic;
	bullet *Blt; 
	TCHAR *NAME;
	float x;
	float y;
	float speed;
	int HP;
	float size;

	int GetKey(); 
	int hantei(bullet Bullet);//作業中
	//////////////////////////////////////////////////////////
	unit();
	unit(class Graphic *app);
	/*~unit();*/
private:
	int shotlock;
};
unit::unit(class Graphic *app):x(400),y(500),speed(4),HP(400),size(32.0),NAME(L""){
	//MessageBox(NULL,L"UNIT",L"コンストラクタ",MB_OK);
	Graphic=app->LoadGr(L"img/F-03.png");//画像のロード
	Blt = new bullet(app);
}
unit::unit(){
//MessageBox(NULL,L"NULL",L"オーバロードされたコンストラクタ 引数:無し",MB_OK);
}




↓まるまる移植したコード。正常に動作します。

コード:

int GameMain::Main(Graphic *app){
	 	 
	static int mode=INITIAL;
	unit *hoge=NULL;
	Eunit *enemy=NULL;

	GameMain *Gmain=NULL;/////////////////////////////////////
	static int lock=0;
	for(;app->RunMessageLoop();){	
		switch (mode){
		case INITIAL:{
			//unit hoge(app);
			hoge = new unit(app);//hogeは流石にそのうち直そう
			enemy= new Eunit(app,10,10,100,1);
			if(lock==0){
				lock=1;
			//	Gmain= new GameMain(app);////////////////////////////////
			}
			mode = MAIN;
		}
		break;
		case MAIN:
			hoge->GetKey();//キー入力
			hoge->Blt->move();//弾の移動
			hoge->Blt->locker=hoge->Blt->locker+1;//弾の発射間隔処理

			enemy->move();//敵の移動
			enemy->hantei(*hoge->Blt); //敵の被弾判定


			/**************描画部**************/
			app->Bpaint();

			app->ClearScreen();
			if((hoge->HP)>0){
				app->paint(hoge->Graphic, hoge->x,hoge->y);//自機
			}
			if((enemy->HP)>0){
				app->paint(enemy->Graphic,enemy->x,enemy->y);
			}
			for(int i=0;i<(hoge->Blt->BltLimit);i++){//メインショット
				if((hoge->Blt->bltpos[i].flug)==1){
					app->paint(hoge->Blt->Graphic,hoge->Blt->bltpos[i].x,hoge->Blt->bltpos[i].y);
				}
			}
			 
			
			
			app->Epaint(); 
			/*********************************/
			//wait();
			Gmain->wait();
			Gmain->FPScheck();
			//mode=END;//仮置き
		break;
		case END:	 
			return 0;
		break;
		}
			 
	 }
	return 0;
}

トントン
記事: 100
登録日時: 15年前

Re: クラスについて

#6

投稿記事 by トントン » 13年前

奥兵 さんが書きました:ためしに動いていたoGameMainの内容に改変を加えずにGameMainクラスのMain関数に移植してみたところ、正常に動作しました。
しかしその状態で関数で宣言しているunitクラスのインスタンスをGameMainクラスのメンバとして確保しようとすると、どう書いてもexeが停止してしまいます。
どのようにして、宣言、確保しようとしたのでしょうか?

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: クラスについて

#7

投稿記事 by へにっくす » 13年前

コード:

unit::unit(class Graphic *app):x(400),y(500),speed(4),HP(400),size(32.0),NAME(L""){
    //MessageBox(NULL,L"UNIT",L"コンストラクタ",MB_OK);
    Graphic=app->LoadGr(L"img/F-03.png");//画像のロード
    Blt = new bullet(app);
}
よく上記でコンパイルできたなあ…
appのクラスであるGraphicと変数名であるGraphicと混同してることといい、
まず変数名とクラス名と区別できるようにした方がよいと思います。
あとGraphicクラスのコードと、その呼び出しのコードも掲示した方が、もっとアドバイスしやすくなると思いますよ
written by へにっくす

奥兵

Re: クラスについて

#8

投稿記事 by 奥兵 » 13年前

へにっくす さんが書きました:

コード:

unit::unit(class Graphic *app):x(400),y(500),speed(4),HP(400),size(32.0),NAME(L""){
    //MessageBox(NULL,L"UNIT",L"コンストラクタ",MB_OK);
    Graphic=app->LoadGr(L"img/F-03.png");//画像のロード
    Blt = new bullet(app);
}
よく上記でコンパイルできたなあ…
appのクラスであるGraphicと変数名であるGraphicと混同してることといい、
まず変数名とクラス名と区別できるようにした方がよいと思います。
あとGraphicクラスのコードと、その呼び出しのコードも掲示した方が、もっとアドバイスしやすくなると思いますよ

ご指摘ありがとうございます。クラスメ名とメンバ変数の名前の被り修正しました。

↓Graphicクラス

コード:

class Graphic
{
public:

	HRESULT hr;

    Graphic();
    ~Graphic();

    HRESULT Initialize();

	
    int RunMessageLoop();

	void paint(ID2D1Bitmap *Gr , float x , float y);
	void ClearScreen();

	HRESULT Bpaint();
	HRESULT Epaint();
	ID2D1Bitmap* LoadGr(TCHAR *text);

private:
	/**********************************/
	
	
	/**********************************/
	
    HRESULT CreateDeviceIndependentResources();
    HRESULT CreateDeviceResources();

    HRESULT CreateGridPatternBrush(
        ID2D1RenderTarget *pRenderTarget,
        ID2D1BitmapBrush **ppBitmapBrush
        );

    void DiscardDeviceResources();

    HRESULT OnRender(ID2D1Bitmap *Gr,float x,float y);//もとのコードでは引数無し

    void OnResize(
        UINT width,
        UINT height
        );

    static LRESULT CALLBACK WndProc(
        HWND hWnd,
        UINT message,
        WPARAM wParam,
        LPARAM lParam
        );

    HRESULT LoadResourceBitmap(
        ID2D1RenderTarget *pRenderTarget,
        IWICImagingFactory *pIWICFactory,
        PCWSTR resourceName,
        PCWSTR resourceType,
        UINT destinationWidth,
        UINT destinationHeight,
        ID2D1Bitmap **ppBitmap
        );

    HRESULT LoadBitmapFromFile(
        ID2D1RenderTarget *pRenderTarget,
        IWICImagingFactory *pIWICFactory,
        PCWSTR uri,
        UINT destinationWidth,
        UINT destinationHeight,
        ID2D1Bitmap **ppBitmap
        );

private:
    HWND m_hwnd;
    ID2D1Factory *m_pD2DFactory;
    IWICImagingFactory *m_pWICFactory;
    IDWriteFactory *m_pDWriteFactory;
    ID2D1HwndRenderTarget *m_pRenderTarget;
    IDWriteTextFormat *m_pTextFormat;
    ID2D1PathGeometry *m_pPathGeometry;
    ID2D1LinearGradientBrush *m_pLinearGradientBrush;
    ID2D1SolidColorBrush *m_pBlackBrush;
    ID2D1BitmapBrush *m_pGridPatternBitmapBrush;
   // ID2D1Bitmap *m_pBitmap;
   // ID2D1Bitmap *m_pAnotherBitmap;
};
↓Graphicクラスの描画部と読み込み部分の関数です

コード:

ID2D1Bitmap* Graphic::LoadGr(TCHAR *text){

	ID2D1Bitmap *Gr=NULL;
	
	if (SUCCEEDED(hr))
        {
            // Create a bitmap by loading it from a file.
            hr = LoadBitmapFromFile(
                m_pRenderTarget,
                m_pWICFactory,
				text,
				0,
                0,
				&Gr
                );
        }
 
	return Gr;
}
void Graphic::paint(ID2D1Bitmap *Gr,float x,float y){//

	HWND Hwnd=m_hwnd;

	PAINTSTRUCT ps;
    BeginPaint(Hwnd, &ps);
    OnRender(Gr,x,y);
	
	EndPaint(Hwnd, &ps); 

}
HRESULT Graphic::OnRender(ID2D1Bitmap *Gr,float x,float y)// 
{
	
     
    if (SUCCEEDED(Graphic::hr) && !(m_pRenderTarget->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED))
    {
        //static const WCHAR sc_helloWorld[] = L"Hello, World!";//テキスト
        // Retrieve the size of the render target.
		//D2D1_SIZE_F renderTargetSize = m_pRenderTarget->GetSize();

        //m_pRenderTarget->BeginDraw();

		//m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
        //m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));//画面を白でクリア
	 
        // Draw a bitmap 
		D2D1_SIZE_F size = Gr->GetSize();
        m_pRenderTarget->DrawBitmap(
			Gr,
            D2D1::RectF(
				x,
				y,//renderTargetSize.height- size.height,
                (x)+size.width,
                (y)+size.height)
	        );
 
        //hr = m_pRenderTarget->EndDraw();

        if (hr == D2DERR_RECREATE_TARGET)
        {
            hr = S_OK;
            DiscardDeviceResources();
        }
    }

    return hr;
}

奥兵

Re: クラスについて

#9

投稿記事 by 奥兵 » 13年前

トントン さんが書きました:
奥兵 さんが書きました:ためしに動いていたoGameMainの内容に改変を加えずにGameMainクラスのMain関数に移植してみたところ、正常に動作しました。
しかしその状態で関数で宣言しているunitクラスのインスタンスをGameMainクラスのメンバとして確保しようとすると、どう書いてもexeが停止してしまいます。
どのようにして、宣言、確保しようとしたのでしょうか?
GameMainクラスのパブリックなメンバに unit *tuni; を加えて
GameMainクラスのコンストラクタで   tuni = new unit(app); としました。

トントン
記事: 100
登録日時: 15年前

Re: クラスについて

#10

投稿記事 by トントン » 13年前

奥兵 さんが書きました:
トントン さんが書きました:
奥兵 さんが書きました:ためしに動いていたoGameMainの内容に改変を加えずにGameMainクラスのMain関数に移植してみたところ、正常に動作しました。
しかしその状態で関数で宣言しているunitクラスのインスタンスをGameMainクラスのメンバとして確保しようとすると、どう書いてもexeが停止してしまいます。
どのようにして、宣言、確保しようとしたのでしょうか?
GameMainクラスのパブリックなメンバに unit *tuni; を加えて
GameMainクラスのコンストラクタで   tuni = new unit(app); としました。
前回の記事からです。
softya(ソフト屋) さんが書きました:
奥兵 さんが書きました:なるほど、インスタンスを作成しただけでLoadGrが使える筈と勘違いしてました。
確認すると正常に動いていたインスタンスのほうはそれらしいメンバ関数いろいろ呼んでました。
この場合LoadGrを使いたければ動いているほうのインスタンスのポインタを渡せばいいんですかね?
unitのインスタンス作成時(コンストラクタが呼ばれるタイミング)で「LoadGrを使いたければ動いているほうのインスタンスのポインタ」が有効でLoadGrが使える状況ならyesです。
そうで無いのならunitのインスタンス生成を遅らせるとかを考えないといけません。
それと、LoadGr()がDemoAppにあるのは何か特別な設計意図があるのでしょうか?オブジェクト指向設計のクラスのメンバとして違和感を感じるのですが。
という状況は考慮していると考えてもよろしいですか?

※後、いくつか気になった点を
1.確認(デバッグ)しやすいように例外処理も入れてみてください。
2.どのようにデバッグしていますか?
最後に編集したユーザー トントン on 2012年10月08日(月) 00:11 [ 編集 1 回目 ]

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: クラスについて

#11

投稿記事 by へにっくす » 13年前

前回の記事から比べると、DemoAppの名前をGraphicに変えただけのように見えますが、なぜ変えたのでしょうね?おそらく
softya(ソフト屋) さんが書きました:オブジェクトがどう構成されていれば分かりやすいかは自ずと分かると思います。
DemoAppと言うクラスにグラフィック系の処理が含まれているとは誰も思わないです。なのに含まれているわけですね。
これに対する修正なのだとは思いますが、Graphicクラスに名前を変えただけですと、
DemoAppクラスにあっても違和感がなかったWndProcとかRunMessageLoopとかOnResizeとかの関数が、
なぜGraphicクラスにあるの?
と思うのです。
言われたことの意味もよく考えず修正してもよけい混乱するだけですよ。

また、appのインスタンスを作成している箇所をコードで示してくれていませんが、まさか作成していないわけじゃないですよね?

コード:

Graphic=app->LoadGr(L"img/F-03.png");//画像のロード
と -> を使用してることから、どっか

コード:

app = new Graphic(); // 確保
みたいな一行があるかと思っていたのですが。
もしないならば落ちて当然、という話になりますよ?
written by へにっくす

奥兵

Re: クラスについて

#12

投稿記事 by 奥兵 » 13年前

Graphicクラスのインスタンスを作成する大元のメイン関数を晒すのを忘れてました。
WinMainはGraphicクラスの本体のコードの一番上にあります。
このクラスはDirect2Dのサンプルを軽くいじったもので、Direct2Dは正直九分九厘意味不明なので
できるだけサンプルから変えないように変えないようにとしてきましたが、内容に矛盾がある以上Graohic的な部分とRunMessageloopみたいなwindowsチックな部分は別のクラスにしなければなりませんね。
何故このクラスがプロシージャやメッセージループを処理していて、どうやって処理しているかも所々理解できなくて・・・
多分デバイスや描画云々とかの理由だとは思うのですが。

↓Graphicクラスのヘッダファイル

コード:

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
//

#pragma once

// Modify the following defines if you have to target a platform prior to the ones specified below.
// Refer to MSDN for the latest info on corresponding values for different platforms.
#ifndef WINVER              // Allow use of features specific to Windows 7 or later.
#define WINVER 0x0700       // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef _WIN32_WINNT        // Allow use of features specific to Windows 7 or later.
#define _WIN32_WINNT 0x0700 // Change this to the appropriate value to target other versions of Windows.
#endif

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>

// C RunTime Header Files
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <wchar.h>
#include <math.h>

#include <d2d1.h>
#include <d2d1helper.h>
#include <dwrite.h>
#include <wincodec.h>

#include "oGameMain.h"



/******************************************************************
*                                                                 *
*  Macros                                                         *
*                                                                 *
******************************************************************/

template<class Interface>
inline void
SafeRelease(
    Interface **ppInterfaceToRelease
    )
{
    if (*ppInterfaceToRelease != NULL)
    {
        (*ppInterfaceToRelease)->Release();

        (*ppInterfaceToRelease) = NULL;
    }
}

#ifndef Assert
#if defined( DEBUG ) || defined( _DEBUG )
#define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0)
#else
#define Assert(b)
#endif //DEBUG || _DEBUG
#endif


#ifndef HINST_THISCOMPONENT
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
#endif



class Graphic
{
public:

	HRESULT hr;

    Graphic();
    ~Graphic();

    HRESULT Initialize();

	
    int RunMessageLoop();

	void paint(ID2D1Bitmap *Gr , float x , float y);
	void ClearScreen();

	HRESULT Bpaint();
	HRESULT Epaint();
	ID2D1Bitmap* LoadGr(TCHAR *text);

private:
	/**********************************/
	
	
	/**********************************/
	
    HRESULT CreateDeviceIndependentResources();
    HRESULT CreateDeviceResources();

    HRESULT CreateGridPatternBrush(
        ID2D1RenderTarget *pRenderTarget,
        ID2D1BitmapBrush **ppBitmapBrush
        );

    void DiscardDeviceResources();

    HRESULT OnRender(ID2D1Bitmap *Gr,float x,float y);//もとのコードでは引数無し

    void OnResize(
        UINT width,
        UINT height
        );

    static LRESULT CALLBACK WndProc(
        HWND hWnd,
        UINT message,
        WPARAM wParam,
        LPARAM lParam
        );

    HRESULT LoadResourceBitmap(
        ID2D1RenderTarget *pRenderTarget,
        IWICImagingFactory *pIWICFactory,
        PCWSTR resourceName,
        PCWSTR resourceType,
        UINT destinationWidth,
        UINT destinationHeight,
        ID2D1Bitmap **ppBitmap
        );

    HRESULT LoadBitmapFromFile(
        ID2D1RenderTarget *pRenderTarget,
        IWICImagingFactory *pIWICFactory,
        PCWSTR uri,
        UINT destinationWidth,
        UINT destinationHeight,
        ID2D1Bitmap **ppBitmap
        );

private:
    HWND m_hwnd;
    ID2D1Factory *m_pD2DFactory;
    IWICImagingFactory *m_pWICFactory;
    IDWriteFactory *m_pDWriteFactory;
    ID2D1HwndRenderTarget *m_pRenderTarget;
    IDWriteTextFormat *m_pTextFormat;
    ID2D1PathGeometry *m_pPathGeometry;
    ID2D1LinearGradientBrush *m_pLinearGradientBrush;
    ID2D1SolidColorBrush *m_pBlackBrush;
    ID2D1BitmapBrush *m_pGridPatternBitmapBrush;
   // ID2D1Bitmap *m_pBitmap;
   // ID2D1Bitmap *m_pAnotherBitmap;
};


↓Graphicクラスの本体

コード:

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved


#include "SimpleDirect2dApplication.h"
#include <tchar.h>
#include "GameMain.h"
 
//
// Provides the entry point to the application.
//

int WINAPI WinMain(
    HINSTANCE /* hInstance */,
    HINSTANCE /* hPrevInstance */, 
    LPSTR /* lpCmdLine */,
    int /* nCmdShow */
    )
{
    // Ignore the return value because we want to continue running even in the
    // unlikely event that HeapSetInformation fails.
    HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
	
    if (SUCCEEDED(CoInitialize(NULL)))
    {
        {
		 Graphic app;
		 
			
            if (SUCCEEDED(app.Initialize()))
            {
				//oGameMain(&app);
				GameMain Gmain(&app);
				Gmain.Main(&app);
				
            }
        }
        CoUninitialize();
    }

    return 0;
}
//
// Initialize members.
//
Graphic::Graphic() :
    m_hwnd(NULL),
    m_pD2DFactory(NULL),
    m_pWICFactory(NULL),
    m_pDWriteFactory(NULL),
    m_pRenderTarget(NULL),
    m_pTextFormat(NULL),
    m_pPathGeometry(NULL),
    m_pLinearGradientBrush(NULL),
    m_pBlackBrush(NULL),
    m_pGridPatternBitmapBrush(NULL)
   // m_pBitmap(NULL),
   //m_pAnotherBitmap(NULL)
{
}

//
// Release resources.
//
Graphic::~Graphic()
{
    SafeRelease(&m_pD2DFactory);
    SafeRelease(&m_pWICFactory);
    SafeRelease(&m_pDWriteFactory);
    SafeRelease(&m_pRenderTarget);
    SafeRelease(&m_pTextFormat);
    SafeRelease(&m_pPathGeometry);
    SafeRelease(&m_pLinearGradientBrush);
    SafeRelease(&m_pBlackBrush);
    SafeRelease(&m_pGridPatternBitmapBrush);
   // SafeRelease(&m_pBitmap);
   // SafeRelease(&m_pAnotherBitmap);
}

//
// Creates the application window and initializes
// device-independent resources.
//
HRESULT Graphic::Initialize()
{
	//DemoApp.hr=CreateDeviceIndependentResources();
	HRESULT hr;
    // Initialize device-indpendent resources, such
    // as the Direct2D factory.
	
    hr=CreateDeviceIndependentResources();
    if (SUCCEEDED(hr))
    {
        // Register the window class.
        WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
        wcex.style         = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc   = Graphic::WndProc;
        wcex.cbClsExtra    = 0;
        wcex.cbWndExtra    = sizeof(LONG_PTR);
        wcex.hInstance     = HINST_THISCOMPONENT;
        wcex.hbrBackground = NULL;
        wcex.lpszMenuName  = NULL;
        wcex.hCursor       = LoadCursor(NULL, IDC_ARROW);
        wcex.lpszClassName = L"D2DDemoApp";

        RegisterClassEx(&wcex);

        // Create the application window.
        //
        // Because the CreateWindow function takes its size in pixels, we
        // obtain the system DPI and use it to scale the window size.
        FLOAT dpiX, dpiY;
        m_pD2DFactory->GetDesktopDpi(&dpiX, &dpiY);

        // Create the application window.
        m_hwnd = CreateWindow(
            L"D2DDemoApp",
            L"WindowTitle",
            WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,//サイズ変更と最大化をブロック 
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            800,//static_cast<UINT>(ceil(800.f * dpiX / 96.f)),
            600,//static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
            NULL,
            NULL,
            HINST_THISCOMPONENT,
            this
            );
        hr = m_hwnd ? S_OK : E_FAIL;
        if (SUCCEEDED(hr))
        {
            ShowWindow(m_hwnd, SW_SHOWNORMAL);
            UpdateWindow(m_hwnd);
        }
    }

    return hr;
}


//
// Create resources which are not bound
// to any device. Their lifetime effectively extends for the
// duration of the app. These resources include the Direct2D,
// DirectWrite, and WIC factories; and a DirectWrite Text Format object
// (used for identifying particular font characteristics) and
// a Direct2D geometry.
//
HRESULT Graphic::CreateDeviceIndependentResources()
{
    static const WCHAR msc_fontName[] = L"Verdana";
    static const FLOAT msc_fontSize = 50;
    HRESULT hr;
    ID2D1GeometrySink *pSink = NULL;

    // Create a Direct2D factory.
    hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pD2DFactory);
    if (SUCCEEDED(hr))
    {
        // Create WIC factory.
        hr = CoCreateInstance(
            CLSID_WICImagingFactory,
            NULL,
            CLSCTX_INPROC_SERVER,
            IID_IWICImagingFactory,
            reinterpret_cast<void **>(&m_pWICFactory)
            );
    }
    if (SUCCEEDED(hr))
    {
        // Create a DirectWrite factory.
        hr = DWriteCreateFactory(
            DWRITE_FACTORY_TYPE_SHARED,
            __uuidof(m_pDWriteFactory),
            reinterpret_cast<IUnknown **>(&m_pDWriteFactory)
            );
    }
    if (SUCCEEDED(hr))
    {
        // Create a DirectWrite text format object.
        hr = m_pDWriteFactory->CreateTextFormat(
            msc_fontName,
            NULL,
            DWRITE_FONT_WEIGHT_NORMAL,
            DWRITE_FONT_STYLE_NORMAL,
            DWRITE_FONT_STRETCH_NORMAL,
            msc_fontSize,
            L"", //locale
            &m_pTextFormat
            );
    }
    if (SUCCEEDED(hr))
    {
        // Center the text horizontally and vertically.
        m_pTextFormat->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);

        m_pTextFormat->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);

        // Create a path geometry.
        hr = m_pD2DFactory->CreatePathGeometry(&m_pPathGeometry);
    }
    if (SUCCEEDED(hr))
    {
        // Use the geometry sink to write to the path geometry.
        hr = m_pPathGeometry->Open(&pSink);
    }
    if (SUCCEEDED(hr))
    {
        pSink->SetFillMode(D2D1_FILL_MODE_ALTERNATE);

        pSink->BeginFigure(
            D2D1::Point2F(0, 0),
            D2D1_FIGURE_BEGIN_FILLED
            );

        pSink->AddLine(D2D1::Point2F(200, 0));

        pSink->AddBezier(
            D2D1::BezierSegment(
                D2D1::Point2F(150, 50),
                D2D1::Point2F(150, 150),
                D2D1::Point2F(200, 200))
            );

        pSink->AddLine(D2D1::Point2F(0, 200));

        pSink->AddBezier(
            D2D1::BezierSegment(
                D2D1::Point2F(50, 150),
                D2D1::Point2F(50, 50),
                D2D1::Point2F(0, 0))
            );

        pSink->EndFigure(D2D1_FIGURE_END_CLOSED);

        hr = pSink->Close();
    }

    SafeRelease(&pSink);

    return hr;
}

//
//  This method creates resources which are bound to a particular
//  Direct3D device. It's all centralized here, in case the resources
//  need to be recreated in case of Direct3D device loss (eg. display
//  change, remoting, removal of video card, etc).
//
HRESULT Graphic::CreateDeviceResources()
{
    HRESULT hr = S_OK;

    if (!m_pRenderTarget)
    {
        RECT rc;
        GetClientRect(m_hwnd, &rc);

        D2D1_SIZE_U size = D2D1::SizeU(
            rc.right - rc.left,
            rc.bottom - rc.top
            );

        // Create a Direct2D render target.
        hr = m_pD2DFactory->CreateHwndRenderTarget(
            D2D1::RenderTargetProperties(),
            D2D1::HwndRenderTargetProperties(m_hwnd, size),
            &m_pRenderTarget
            );
        if (SUCCEEDED(hr))
        {
            // Create a black brush.
            hr = m_pRenderTarget->CreateSolidColorBrush(
                D2D1::ColorF(D2D1::ColorF::Black),
                &m_pBlackBrush
                );
        }
        if (SUCCEEDED(hr))
        {
            ID2D1GradientStopCollection *pGradientStops = NULL;
            // Create a linear gradient.
            static const D2D1_GRADIENT_STOP stops[] =
            {
                {   0.f,  { 0.f, 1.f, 1.f, 0.25f }  },
                {   1.f,  { 0.f, 0.f, 1.f, 1.f }  },
            };

            hr = m_pRenderTarget->CreateGradientStopCollection(
                stops,
                ARRAYSIZE(stops),
                &pGradientStops
                );
            if (SUCCEEDED(hr))
            {
                hr = m_pRenderTarget->CreateLinearGradientBrush(
                    D2D1::LinearGradientBrushProperties(
                        D2D1::Point2F(100, 0),
                        D2D1::Point2F(100, 200)),
                    D2D1::BrushProperties(),
                    pGradientStops,
                    &m_pLinearGradientBrush
                    );
                pGradientStops->Release();
            }
        }
      
        if (SUCCEEDED(hr))
        {
            hr = CreateGridPatternBrush(m_pRenderTarget, &m_pGridPatternBitmapBrush);
        }
    }

    return hr;
}
//LoadGraphics
ID2D1Bitmap* Graphic::LoadGr(TCHAR *text){

	ID2D1Bitmap *Gr=NULL;
	
	if (SUCCEEDED(hr))
        {
            // Create a bitmap by loading it from a file.
            hr = LoadBitmapFromFile(
                m_pRenderTarget,
                m_pWICFactory,
				text,
				0,
                0,
				&Gr
                );
        }
 
	return Gr;
}
//
// Creates a pattern brush.
//
HRESULT Graphic::CreateGridPatternBrush(
    ID2D1RenderTarget *pRenderTarget,
    ID2D1BitmapBrush **ppBitmapBrush
    )
{
    HRESULT hr = S_OK;

    // Create a compatible render target.
    ID2D1BitmapRenderTarget *pCompatibleRenderTarget = NULL;
    hr = pRenderTarget->CreateCompatibleRenderTarget(
        D2D1::SizeF(10.0f, 10.0f),
        &pCompatibleRenderTarget
        );
    if (SUCCEEDED(hr))
    {
        // Draw a pattern.
        ID2D1SolidColorBrush *pGridBrush = NULL;
        hr = pCompatibleRenderTarget->CreateSolidColorBrush(
            D2D1::ColorF(D2D1::ColorF(0.93f, 0.94f, 0.96f, 1.0f)),
            &pGridBrush
            );
        if (SUCCEEDED(hr))
        {
            pCompatibleRenderTarget->BeginDraw();
            pCompatibleRenderTarget->FillRectangle(D2D1::RectF(0.0f, 0.0f, 10.0f, 1.0f), pGridBrush);
            pCompatibleRenderTarget->FillRectangle(D2D1::RectF(0.0f, 0.1f, 1.0f, 10.0f), pGridBrush);
            pCompatibleRenderTarget->EndDraw();

            // Retrieve the bitmap from the render target.
            ID2D1Bitmap *pGridBitmap = NULL;
            hr = pCompatibleRenderTarget->GetBitmap(&pGridBitmap);
            if (SUCCEEDED(hr))
            {
                // Choose the tiling mode for the bitmap brush.
                D2D1_BITMAP_BRUSH_PROPERTIES brushProperties =
                    D2D1::BitmapBrushProperties(D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_WRAP);

                // Create the bitmap brush.
                hr = m_pRenderTarget->CreateBitmapBrush(pGridBitmap, brushProperties, ppBitmapBrush);

                pGridBitmap->Release();
            }

            pGridBrush->Release();
        }

        pCompatibleRenderTarget->Release();
    }

    return hr;
}

//
//  Discard device-specific resources which need to be recreated
//  when a Direct3D device is lost
//
void Graphic::DiscardDeviceResources()
{
    SafeRelease(&m_pRenderTarget);
   // SafeRelease(&m_pBitmap);
    SafeRelease(&m_pBlackBrush);
    SafeRelease(&m_pLinearGradientBrush);
  //  SafeRelease(&m_pAnotherBitmap);
    SafeRelease(&m_pGridPatternBitmapBrush);
}

//
// The main window message loop.
//
int Graphic::RunMessageLoop()
{
	
    MSG msg;
	//HWND

	hr=CreateDeviceResources(); 
	//for(;;){
	
		if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)!=0){
			
			if (!GetMessage (&msg,NULL,0,0)){//WM_QUITが来てた時の /* メッセージ処理 */
				//MessageBox(NULL,L"終了処理",L"てすてす",MB_OK);
				return 0;
			} 
			
			TranslateMessage(&msg);
			DispatchMessage(&msg);
			//MessageBox(NULL,L"PM後",L"てすてす",MB_OK);
		}
	 
	return 1;
	//}

}
void Graphic::paint(ID2D1Bitmap *Gr,float x,float y){//

	HWND Hwnd=m_hwnd;

	PAINTSTRUCT ps;
    BeginPaint(Hwnd, &ps);
    OnRender(Gr,x,y);
	
	EndPaint(Hwnd, &ps); 

}
HRESULT Graphic::Bpaint(){
	m_pRenderTarget->BeginDraw();
	return 0;
}

HRESULT Graphic::Epaint(){
	hr = m_pRenderTarget->EndDraw();
	return 0;
}
void Graphic::ClearScreen(){

	//m_pRenderTarget->BeginDraw();
	m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));//画面を白でクリア
	//m_pRenderTarget->EndDraw();

}
HRESULT Graphic::OnRender(ID2D1Bitmap *Gr,float x,float y)// 
{
	if(Gr==NULL){
		MessageBox(NULL,L"画像が読みこまれていません。",L"エラー",MB_OK);
		return -1;
	}
     
    if (SUCCEEDED(Graphic::hr) && !(m_pRenderTarget->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED))
    {
        //static const WCHAR sc_helloWorld[] = L"Hello, World!";//テキスト
        // Retrieve the size of the render target.
		//D2D1_SIZE_F renderTargetSize = m_pRenderTarget->GetSize();

        //m_pRenderTarget->BeginDraw();

		//m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
        //m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));//画面を白でクリア
	 
        // Draw a bitmap 
		D2D1_SIZE_F size = Gr->GetSize();
        m_pRenderTarget->DrawBitmap(
			Gr,
            D2D1::RectF(
				x,
				y,//renderTargetSize.height- size.height,
                (x)+size.width,
                (y)+size.height)
	        );
 
        //hr = m_pRenderTarget->EndDraw();

        if (hr == D2DERR_RECREATE_TARGET)
        {
            hr = S_OK;
            DiscardDeviceResources();
        }
    }

    return hr;
}

//
//  If the application receives a WM_SIZE message, this method
//  resize the render target appropriately.
//
void Graphic::OnResize(UINT width, UINT height)
{
    if (m_pRenderTarget)
    {
        D2D1_SIZE_U size;
        size.width = width;
        size.height = height;

        // Note: This method can fail, but it's okay to ignore the
        // error here -- it will be repeated on the next call to
        // EndDraw.
        m_pRenderTarget->Resize(size);
    }
}


//
// The window message handler.
//
//注)多分ここで開始、終了、読み込み等の処理を行なっている気がするので移植する必要あり 
LRESULT CALLBACK Graphic::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    LRESULT result = 0;


    if (message == WM_CREATE)
    {
		 
        LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
        Graphic *pGraphic = (Graphic *)pcs->lpCreateParams;

        ::SetWindowLongPtrW(
            hwnd,
            GWLP_USERDATA,
            PtrToUlong(pGraphic)
            );

		//HWND hWnd;
		/*IntPtr hMenu = GetSystemMenu(hWnd, 0);
		RemoveMenu(hWnd,SC_MINIMIZE);		*/

        result = 1;
    }
    else
    {
        Graphic *pGraphic = reinterpret_cast<Graphic *>(static_cast<LONG_PTR>(
            ::GetWindowLongPtrW(
                hwnd,
                GWLP_USERDATA
                )));

        bool wasHandled = false;

        if (pGraphic)
        {
            switch (message)
            {
            case WM_SIZE://
                {
                    UINT width = LOWORD(lParam);
                    UINT height = HIWORD(lParam);
                    pGraphic->OnResize(width, height);
                }
                result = 0;
                wasHandled = true;
                break;
			 
            case WM_DESTROY:
                {
                    PostQuitMessage(0);
                }
				 
                result = 1;
                wasHandled = true;
                break;
				case WM_ERASEBKGND:
				{
					return FALSE;
				}

            }
        }

        if (!wasHandled)
        {
            result = DefWindowProc(hwnd, message, wParam, lParam);
        }
    }


    return result;
}

//
// Creates a Direct2D bitmap from a resource in the
// application resource file.
//
HRESULT Graphic::LoadResourceBitmap(
    ID2D1RenderTarget *pRenderTarget,
    IWICImagingFactory *pIWICFactory,
    PCWSTR resourceName,
    PCWSTR resourceType,
    UINT destinationWidth,
    UINT destinationHeight,
    ID2D1Bitmap **ppBitmap
    )
{
    HRESULT hr = S_OK;
    IWICBitmapDecoder *pDecoder = NULL;
    IWICBitmapFrameDecode *pSource = NULL;
    IWICStream *pStream = NULL;
    IWICFormatConverter *pConverter = NULL;
    IWICBitmapScaler *pScaler = NULL;

    HRSRC imageResHandle = NULL;
    HGLOBAL imageResDataHandle = NULL;
    void *pImageFile = NULL;
    DWORD imageFileSize = 0;

    // Locate the resource.
    imageResHandle = FindResourceW(HINST_THISCOMPONENT, resourceName, resourceType);

    hr = imageResHandle ? S_OK : E_FAIL;
    if (SUCCEEDED(hr))
    {
        // Load the resource.
        imageResDataHandle = LoadResource(HINST_THISCOMPONENT, imageResHandle);

        hr = imageResDataHandle ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(hr))
    {
        // Lock it to get a system memory pointer.
        pImageFile = LockResource(imageResDataHandle);

        hr = pImageFile ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(hr))
    {
        // Calculate the size.
        imageFileSize = SizeofResource(HINST_THISCOMPONENT, imageResHandle);

        hr = imageFileSize ? S_OK : E_FAIL;
    }
    if (SUCCEEDED(hr))
    {
        // Create a WIC stream to map onto the memory.
        hr = pIWICFactory->CreateStream(&pStream);
    }
    if (SUCCEEDED(hr))
    {
        // Initialize the stream with the memory pointer and size.
        hr = pStream->InitializeFromMemory(
            reinterpret_cast<BYTE*>(pImageFile),
            imageFileSize
            );
    }
    if (SUCCEEDED(hr))
    {
        // Create a decoder for the stream.
        hr = pIWICFactory->CreateDecoderFromStream(
            pStream,
            NULL,
            WICDecodeMetadataCacheOnLoad,
            &pDecoder
            );
    }
    if (SUCCEEDED(hr))
    {
        // Create the initial frame.
        hr = pDecoder->GetFrame(0, &pSource);
    }
    if (SUCCEEDED(hr))
    {
        // Convert the image format to 32bppPBGRA
        // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
        hr = pIWICFactory->CreateFormatConverter(&pConverter);
    }
    if (SUCCEEDED(hr))
    {
        // If a new width or height was specified, create an
        // IWICBitmapScaler and use it to resize the image.
        if (destinationWidth != 0 || destinationHeight != 0)
        {
            UINT originalWidth, originalHeight;
            hr = pSource->GetSize(&originalWidth, &originalHeight);
            if (SUCCEEDED(hr))
            {
                if (destinationWidth == 0)
                {
                    FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
                    destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
                }
                else if (destinationHeight == 0)
                {
                    FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
                    destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
                }

                hr = pIWICFactory->CreateBitmapScaler(&pScaler);
                if (SUCCEEDED(hr))
                {
                    hr = pScaler->Initialize(
                            pSource,
                            destinationWidth,
                            destinationHeight,
                            WICBitmapInterpolationModeCubic
                            );
                    if (SUCCEEDED(hr))
                    {
                        hr = pConverter->Initialize(
                            pScaler,
                            GUID_WICPixelFormat32bppPBGRA,
                            WICBitmapDitherTypeNone,
                            NULL,
                            0.f,
                            WICBitmapPaletteTypeMedianCut
                            );
                    }
                }
            }
        }
        else
        {
            hr = pConverter->Initialize(
                pSource,
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                NULL,
                0.f,
                WICBitmapPaletteTypeMedianCut
                );
        }
    }
    if (SUCCEEDED(hr))
    {
        //create a Direct2D bitmap from the WIC bitmap.
        hr = pRenderTarget->CreateBitmapFromWicBitmap(
            pConverter,
            NULL,
            ppBitmap
            );
    }

    SafeRelease(&pDecoder);
    SafeRelease(&pSource);
    SafeRelease(&pStream);
    SafeRelease(&pConverter);
    SafeRelease(&pScaler);

    return hr;
}

//
// Creates a Direct2D bitmap from the specified
// file name.
//
HRESULT Graphic::LoadBitmapFromFile(
    ID2D1RenderTarget *pRenderTarget,
    IWICImagingFactory *pIWICFactory,
    PCWSTR uri,
    UINT destinationWidth,
    UINT destinationHeight,
    ID2D1Bitmap **ppBitmap
    )
{
    HRESULT hr = S_OK;

    IWICBitmapDecoder *pDecoder = NULL;
    IWICBitmapFrameDecode *pSource = NULL;
    IWICStream *pStream = NULL;
    IWICFormatConverter *pConverter = NULL;
    IWICBitmapScaler *pScaler = NULL;

    hr = pIWICFactory->CreateDecoderFromFilename(
        uri,
        NULL,
        GENERIC_READ,
        WICDecodeMetadataCacheOnLoad,
        &pDecoder
        );
    if (SUCCEEDED(hr))
    {
        // Create the initial frame.
        hr = pDecoder->GetFrame(0, &pSource);
    }

    if (SUCCEEDED(hr))
    {
        // Convert the image format to 32bppPBGRA
        // (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
        hr = pIWICFactory->CreateFormatConverter(&pConverter);
    }
    if (SUCCEEDED(hr))
    {
        // If a new width or height was specified, create an
        // IWICBitmapScaler and use it to resize the image.
        if (destinationWidth != 0 || destinationHeight != 0)
        {
            UINT originalWidth, originalHeight;
            hr = pSource->GetSize(&originalWidth, &originalHeight);
            if (SUCCEEDED(hr))
            {
                if (destinationWidth == 0)
                {
                    FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
                    destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
                }
                else if (destinationHeight == 0)
                {
                    FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
                    destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
                }

                hr = pIWICFactory->CreateBitmapScaler(&pScaler);
                if (SUCCEEDED(hr))
                {
                    hr = pScaler->Initialize(
                            pSource,
                            destinationWidth,
                            destinationHeight,
                            WICBitmapInterpolationModeCubic
                            );
                }
                if (SUCCEEDED(hr))
                {
                    hr = pConverter->Initialize(
                        pScaler,
                        GUID_WICPixelFormat32bppPBGRA,
                        WICBitmapDitherTypeNone,
                        NULL,
                        0.f,
                        WICBitmapPaletteTypeMedianCut
                        );
                }
            }
        }
        else // Don't scale the image.
        {
            hr = pConverter->Initialize(
                pSource,
                GUID_WICPixelFormat32bppPBGRA,
                WICBitmapDitherTypeNone,
                NULL,
                0.f,
                WICBitmapPaletteTypeMedianCut
                );
        }
    }
    if (SUCCEEDED(hr))
    {
        // Create a Direct2D bitmap from the WIC bitmap.
        hr = pRenderTarget->CreateBitmapFromWicBitmap(
            pConverter,
            NULL,
            ppBitmap
            );
    }

    SafeRelease(&pDecoder);
    SafeRelease(&pSource);
    SafeRelease(&pStream);
    SafeRelease(&pConverter);
    SafeRelease(&pScaler);

    return hr;
}


アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: クラスについて

#13

投稿記事 by へにっくす » 13年前

あーなるほど
サンプル - Direct2D (MSDN)
ここからもってきたのね
どのサンプルから持ってきたのかは知りませんが、手を入れるところを間違ってます。
どうやらRunMessageLoopをGmain.Main(&app);に置き換えているようですが、
いじるのは、WndProcの方ですよ。それ以外はいじってはいけません。
Windowsで開発している人なら、すぐわかることなんですけどね。
※このことは、それぞれのサンプルを落として、比較しても分かることかと。(RunMessageLoopのくだりは変化なしのはず)
またここから持ってきたことを最初に言っとけば、DemoApp→Graphicの変更も言われることはなかったと思いますよ。

そもそもこのサンプルは、Windows開発に慣れている人が、初めてDirect2Dに触れる際にチュートリアルとして用意されているものです。
つまり貴方のやってることは、基本的なことを理解しないで、いきなり応用編をやろうとしてるのと同じです。
基礎的な理解がなければ無理ですよ。
せめて下の、SDK編第一部ぐらいはマスターしてくださいね。
猫でもわかるプログラミング
written by へにっくす

奥兵

Re: クラスについて

#14

投稿記事 by 奥兵 » 12年前

お返事ありがとうございます。
元のソースだとGetMessageでメッセージを処理していたので、とりあえずゲームのソースを書きたかったので
適当にPeekMessageのループに変更を加えてみたのですが不味いですかね?
WinMainでGameMainを呼んで、RunMessageLoop()はGameMainのMain関数で毎ループ呼ぶことにしています。

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: クラスについて

#15

投稿記事 by へにっくす » 12年前

奥兵 さんが書きました:お返事ありがとうございます。
元のソースだとGetMessageでメッセージを処理していたので、とりあえずゲームのソースを書きたかったので
適当にPeekMessageのループに変更を加えてみたのですが不味いですかね?
WinMainでGameMainを呼んで、RunMessageLoop()はGameMainのMain関数で毎ループ呼ぶことにしています。
まずいと言っているのです。
ウィンドウを作成していて、その中の関数WndProcで描画関数を書くべきなのに、外で描画処理を行おうとしていることが問題です。
正常に動いているのはたまたまです。私から見れば落ちて当然のコードを組んでいるように見えるのです。
RunMessageLoopの下りは元に戻して、WndProc関数をいじるようにしてください。
その修正をしたら、もう一度コードを示して下さい。
written by へにっくす

奥兵

Re: クラスについて

#16

投稿記事 by 奥兵 » 12年前

元のサンプルソースのメッセージループがこれで

コード:

void DemoApp::RunMessageLoop()
{
    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
↓現在のソースがこれなんですが

コード:

int Graphic::RunMessageLoop()
{	
    MSG msg;

	hr=CreateDeviceResources(); 
	
		if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE)!=0){	
			if (!GetMessage (&msg,NULL,0,0)){//WM_QUITが来てた時の /* メッセージ処理 */
				return 0;
			} 
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	 
	return 1;
	
}
理解力低くてごめんなさい。
ゲームループ実装の方法をぐぐったらPeekMessageを使う方法がHItしたのでそれでゲームループを実現したのですが、GetMessageに戻す場合どうするべきかわかりません。

奥兵

Re: クラスについて

#17

投稿記事 by 奥兵 » 12年前

たくさんのアドバイスを頂いているなか非常に申し訳ないのですが、研修で2日程家を開けなければならないので2日程の間お返事できません。

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: クラスについて

#18

投稿記事 by へにっくす » 12年前

奥兵 さんが書きました:元のサンプルソースのメッセージループがこれで

コード:

void DemoApp::RunMessageLoop()
{
    MSG msg;

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}
このコードに戻せと言ってるのです。
すなわち、もう一度DemoAppのソースからやり直せと言ってるのですよ。
せっかく自分で見つけたコードがおしいのは分かるのですが、
使い方を間違ってちゃ、意味がないんですよ。
それをひきずったまま修正しようとすると泥沼ですよ。

元のWinMainは次のような関数になっていたかと思うのですが

コード:

int WINAPI WinMain(
    HINSTANCE /* hInstance */,
    HINSTANCE /* hPrevInstance */,
    LPSTR /* lpCmdLine */,
    int /* nCmdShow */
    )
{
    // Ignore the return value because we want to continue running even in the
    // unlikely event that HeapSetInformation fails.
    HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);

    if (SUCCEEDED(CoInitialize(NULL)))
    {
        {
            DemoApp app;

            if (SUCCEEDED(app.Initialize()))
            {
                app.RunMessageLoop();
            }
        }
        CoUninitialize();
    }

    return 0;
}
ここの部分はいじらないでください。
RunMessageLoop関数の中もです。
いじるのは以下の関数です。

コード:

LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   // ここ!!
}
written by へにっくす

奥兵

Re: クラスについて

#19

投稿記事 by 奥兵 » 12年前

お返事ありがとうございます。
せっかくご指摘いただいたので早速ソースをいじりたいのはやまやまなのですが、申し訳ありませんが研修の為家を離れればならず今日から2日お返事できません。
帰ったら早速書きなおしてみます。

naohiro19
記事: 256
登録日時: 15年前
住所: 愛知県

Re: クラスについて

#20

投稿記事 by naohiro19 » 12年前

奥兵 さんが書きました:お返事ありがとうございます。
せっかくご指摘いただいたので早速ソースをいじりたいのはやまやまなのですが、申し訳ありませんが研修の為家を離れればならず今日から2日お返事できません。
帰ったら早速書きなおしてみます。
答えになっていません

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: クラスについて

#21

投稿記事 by へにっくす » 12年前

奥兵 さんが書きました:お返事ありがとうございます。
せっかくご指摘いただいたので早速ソースをいじりたいのはやまやまなのですが、申し訳ありませんが研修の為家を離れればならず今日から2日お返事できません。
帰ったら早速書きなおしてみます。
別に急げとは言ってないので、大丈夫ですよ。
出来たらでいいですから、ゆっくり考えてくださいね。
written by へにっくす

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: クラスについて

#22

投稿記事 by ISLe » 12年前

naohiro19 さんが書きました:
奥兵 さんが書きました:お返事ありがとうございます。
せっかくご指摘いただいたので早速ソースをいじりたいのはやまやまなのですが、申し訳ありませんが研修の為家を離れればならず今日から2日お返事できません。
帰ったら早速書きなおしてみます。
答えになっていません
回答を導くまでの過程を否定されるのであれば、提示された情報では足りないからもっと情報出せという回答などにも同様になさるべきでは?
質問者だけを非難するのは卑怯ではありませんか?

閑話休題
ゲームループを抱え込むのが良くない設計だというのはこの掲示板でさんざん言われていることですね。

奥兵

Re: クラスについて

#23

投稿記事 by 奥兵 » 12年前

Graphicクラスから不自然だったメッセージループやプロシージャをDemoAppクラスのような形にしてに外し、
DemoAppクラスのプロシージャ内でGraphicクラスのインスタンスやGameMainのインスタンスを作成するようにして、
ループはDemoAppで実現させます。
そうした場合GetMessage関数で処理が止まると思うのですが、どうすればいいのでしょうか?

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: クラスについて

#24

投稿記事 by へにっくす » 12年前

奥兵 さんが書きました:Graphicクラスから不自然だったメッセージループやプロシージャをDemoAppクラスのような形にしてに外し、
DemoAppクラスのプロシージャ内でGraphicクラスのインスタンスやGameMainのインスタンスを作成するようにして、
ループはDemoAppで実現させます。
そうした場合GetMessage関数で処理が止まると思うのですが、どうすればいいのでしょうか?
その場合はPeekMessage使えばよろしい。
PeekMessageによる「メインループ」
私が問題にしてるのは、描画する処理をWndProc関数でしていない点ですからね。
オフトピック
元のソースからやり直せと言ってるのに、RunMessageLoop関数はいじるなとも言ってるのに、GraphicクラスやらGetMessage関数云々が出てくるということは、私の助言を全然聞いていない予感がするんですが…
(その質問は、元のソースからやり直した後の話だと思うので)
written by へにっくす

奥兵

Re: クラスについて

#25

投稿記事 by 奥兵 » 12年前

ごめんなさいGetMessage関数について勘違いをしてたみたいです。大変失礼致しました。

閉鎖

“C言語何でも質問掲示板” へ戻る