ico/TaskIco.cpp
author Issei Suzuki <issei@issei.org>
Wed Sep 12 23:18:01 2007 +0900 (16 months ago)
changeset 630 df72cb41e9e8
parent 627c6a7d2ca7e88
child 63559e2bbeccdc4
permissions -rw-r--r--
ico ザルガラー多面体モデル表示のテスト実装
・モデルは a03 固定
・調整機能なし
        1 /*
        2  * サンプルタスク
        3  * $Id: TaskIco.cpp 185 2006-10-22 22:30:10Z issei $
        4  *
        5  * Copyright (c) 2006
        6  *    Issei Suzuki <issei@issei.org>   All rights reserved.
        7  *
        8  * Permission is hereby granted, free of charge, to any person obtaining a
        9  * copy of this software and associated documentation files (the "Software"),
       10  * to deal in the Software without restriction, including without limitation
       11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       12  * and/or sell copies of the Software, and to permit persons to whom the
       13  * Software is furnished to do so, subject to the following conditions:
       14  *
       15  * The above copyright notice and this permission notice shall be included
       16  * in all copies or substantial portions of the Software.
       17  *
       18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
       21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
       23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
       24  * DEALINGS IN THE SOFTWARE.
       25  */
       26 
       27 #include "StdAfx.h"
       28 #include "TaskIco.h"
       29 #include "D3D.h"
       30 #include "DIDev.h"
       31 #include "D3DRes.h"
       32 #include "Hsm.h"
       33 #include "PackfileManager.h"
       34 #include "PackfileHandle.h"
       35 #include "../tool/src/icodata/polyinfo.h"
       36 #include "data/polyinfo.packh"
       37 
       38 // TODO デバイス消失時に頂点バッファを作り直す
       39 
       40 ANON_NAMESPACE_BEGIN
       41 
       42 class TaskIco;
       43 
       44 class Event
       45 	: public HsmEventBase<TaskIco, Event>
       46 {
       47 public:
       48 	enum {
       49 		NSIG_DRAW,
       50 		NSIG_EXEC,
       51 		NSIG_LOST_DEVICE,
       52 		NSIG_RESET_DEVICE,
       53 	};
       54 
       55 	static Event CreateDraw() { return Event(NSIG_DRAW); }
       56 	static Event CreateExec() { return Event(NSIG_EXEC); }
       57 	static Event CreateLostDevice() { return Event(NSIG_LOST_DEVICE); }
       58 	static Event CreateResetDevice() { return Event(NSIG_RESET_DEVICE); }
       59 
       60 private:
       61 	Event(int nsig) : HsmEventBase(nsig) {}
       62 
       63 	friend class HsmEventBase<TaskIco, Event>;
       64 };
       65 
       66 
       67 class TaskIco
       68 	: public ITask
       69 	, public ID3DRes
       70 	, public HsmBase<TaskIco, Event>
       71 {
       72 public:
       73 	TaskIco();
       74 	virtual ~TaskIco();
       75 	virtual TASK_PRIO_TYPE getPrio() const { return TASK_PRIO_NORMAL; }
       76 	virtual TASK_DPRIO_TYPE getDPrio() const { return TASK_DPRIO_NORMAL; }
       77 	virtual void exec(ICtxTask& /*ctx*/, TASK_PRIO_TYPE prio);
       78 	virtual void draw(ICtxTask const& /*ctx*/, TASK_DPRIO_TYPE dprio) const;
       79 	virtual bool isTerminated() const { return HSM_ISIN(&TaskIco::_stateTerm); }
       80 
       81 	// ID3DRes
       82 	virtual void onLostDevice();
       83 	virtual void onResetDevice();
       84 
       85 private:
       86 	struct CUSTOMVERTEX
       87 	{
       88 		D3DXVECTOR3 position;
       89 		D3DXVECTOR3 normal;
       90 	};
       91 	enum { D3DFVF_CUSTOMVERTEX = D3DFVF_XYZ | D3DFVF_NORMAL };
       92 
       93 	PackfileHandle<MEM_SEG_ICO> m_pack;
       94 	int m_load_count;
       95 	PolyVertList const* m_pPoly;
       96 	CComPtr<IDirect3DVertexBuffer9> m_spVtxBuf;
       97 	FLOAT m_fAngle;
       98 
       99 	bool _initModel();
      100 	void _releaseModel();
      101 	void _setLight() const;
      102 	void _setCamera() const;
      103 	void _drawModel() const;
      104 
      105 	// 状態関数
      106 	HsmState _stateMemAlloc(Event const& e);
      107 		HsmState _stateLoad(Event const& e);
      108 		HsmState _stateMain(Event const& e);
      109 	HsmState _stateTerm(Event const& e);
      110 
      111 	REF_COUNT_IMPL(TaskIco)
      112 };
      113 ANON_NAMESPACE_END
      114 
      115 TaskIco::TaskIco()
      116  	: HsmBase<TaskIco, Event>(&TaskIco::_stateLoad)
      117 	, m_load_count(0)
      118 	, m_pPoly(NULL)
      119 	, m_fAngle(0.0f)
      120 {
      121 	initHsm();
      122 }
      123 
      124 TaskIco::~TaskIco()
      125 {}
      126 
      127 void TaskIco::exec(ICtxTask& /*ctx*/, TASK_PRIO_TYPE /*prio*/)
      128 {
      129 	dispatchHsm(Event::CreateExec());
      130 }
      131 
      132 void TaskIco::draw(ICtxTask const& /*ctx*/, TASK_DPRIO_TYPE /*dprio*/) const
      133 {
      134 	dbConsLocate(0, 1);
      135 	dbConsPrintf(_T("ICO App"));
      136 	const_cast<TaskIco*>(this)->dispatchHsm(Event::CreateDraw());
      137 }
      138 
      139 void TaskIco::onLostDevice()
      140 {
      141 	dispatchHsm(Event::CreateLostDevice());
      142 }
      143 
      144 void TaskIco::onResetDevice()
      145 {
      146 	dispatchHsm(Event::CreateResetDevice());
      147 }
      148 
      149 bool TaskIco::_initModel()
      150 {
      151 	PolyVertList const* pPoly = NULL;
      152 	m_pack.getResIdx(&pPoly, 1);
      153 
      154 	CComPtr<IDirect3DVertexBuffer9> spVtxBuf;
      155 	HRESULT hr = g_d3ddev.CreateVertexBuffer(
      156 		static_cast<UINT>(sizeof(PolyVertList::CustomVertex) * pPoly->vertex_count),
      157 		0,
      158 		D3DFVF_CUSTOMVERTEX,
      159 		D3DPOOL_DEFAULT,
      160 		&spVtxBuf,
      161 		NULL);
      162 	if (FAILED(hr))
      163 		return false;
      164 
      165 	void* pVtxBuf = NULL;
      166 	hr = spVtxBuf->Lock(0, 0, &pVtxBuf, 0);
      167 	if (FAILED(hr))
      168 		return false;
      169 	::memcpy(pVtxBuf, pPoly->vertex_list, sizeof(PolyVertList::CustomVertex) * pPoly->vertex_count);
      170 	spVtxBuf->Unlock();
      171 
      172 	m_pPoly = pPoly;
      173 	m_spVtxBuf = spVtxBuf;
      174 
      175 	return true;
      176 }
      177 
      178 void TaskIco::_releaseModel()
      179 {
      180 	m_pPoly = NULL;
      181 	m_spVtxBuf.Release();
      182 
      183 }
      184 
      185 void TaskIco::_setLight() const
      186 {
      187 	// ライテイング
      188 	D3DLIGHT9 light;
      189 	::ZeroMemory(&light, sizeof(light));
      190 	light.Type		= D3DLIGHT_DIRECTIONAL;
      191 	light.Diffuse.r	= 0.8f;
      192 	light.Diffuse.g	= 0.8f;
      193 	light.Diffuse.b	= 0.8f;
      194 	D3DXVECTOR3 vecDir(-1.0f, +1.0f, -5.0f);
      195 	D3DXVec3Normalize(reinterpret_cast<D3DXVECTOR3*>(&light.Direction), &vecDir);
      196 
      197 	g_d3ddev.SetLight(0, &light);
      198 	g_d3ddev.LightEnable(0, TRUE);
      199 	g_d3ddev.SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(64, 64, 64));
      200 	g_d3ddev.SetRenderState(D3DRS_LIGHTING, TRUE);
      201 }
      202 
      203 void TaskIco::_setCamera() const
      204 {
      205 	// 視点設定
      206 	static D3DXVECTOR3 const vecViewEye		(0.0f, 3.0f,-5.0f);
      207 	static D3DXVECTOR3 const vecViewLookAt	(0.0f, 0.0f, 0.0f);
      208 	static D3DXVECTOR3 const vecViewUp		(0.0f, 1.0f, 0.0f);
      209 	D3DXMATRIX matView;
      210 	D3DXMatrixLookAtLH(&matView, &vecViewEye, &vecViewLookAt, &vecViewUp);
      211 	g_d3ddev.SetTransform(D3DTS_VIEW, &matView);
      212 
      213 	// 投影
      214 	D3DXMATRIX matProj;
      215 	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);
      216 	g_d3ddev.SetTransform(D3DTS_PROJECTION, &matProj);
      217 }
      218 
      219 void TaskIco::_drawModel() const
      220 {
      221 	g_d3ddev.SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);	// TODO
      222 	g_d3ddev.SetRenderState(D3DRS_ZENABLE, TRUE);
      223 	g_d3ddev.SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
      224 
      225 	D3DXMATRIX matWorld;
      226 	D3DXMatrixIdentity(&matWorld);
      227 	D3DXMatrixRotationY(&matWorld, m_fAngle);
      228 	g_d3ddev.SetTransform(D3DTS_WORLD, &matWorld);
      229 
      230 	D3DMATERIAL9 mtrl;
      231 	::ZeroMemory(&mtrl, sizeof(mtrl));
      232 	mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
      233 	mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
      234 	mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
      235 	mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
      236 	g_d3ddev.SetMaterial(&mtrl);
      237 
      238 	g_d3ddev.SetStreamSource(0, m_spVtxBuf, 0, sizeof(PolyVertList::CustomVertex));
      239 	g_d3ddev.SetFVF(D3DFVF_CUSTOMVERTEX);
      240 	for (PolyVertList::IndexRange const* p = m_pPoly->index_list; p->count > 0; ++p)
      241 		g_d3ddev.DrawPrimitive(D3DPT_TRIANGLEFAN, p->first, p->count);
      242 }
      243 
      244 TaskIco::HsmState TaskIco::_stateMemAlloc(Event const& e)
      245 {
      246 	switch (e.getSignal()) {
      247 	case Event::NSIG_ENTER:
      248 		g_pack.createSegment(MEM_SEG_ICO, MEM_SEG_ICO_SIZE);
      249 		return 0;
      250 	case Event::NSIG_EXIT:
      251 		m_pack.release();
      252 		g_pack.breakSegment(MEM_SEG_ICO);
      253 		return 0;
      254 	}
      255 	return HSM_TOP();
      256 }
      257 
      258 
      259 TaskIco::HsmState TaskIco::_stateLoad(Event const& e)
      260 {
      261 	switch (e.getSignal()) {
      262 	case Event::NSIG_ENTER:
      263 		m_pack.load(POLYINFO_PACK);
      264 		return 0;
      265 	case Event::NSIG_EXEC:
      266 		++m_load_count;
      267 		if (m_pack.isLoaded())
      268 			HSM_TRAN(&TaskIco::_stateMain);
      269 		return 0;
      270 	case Event::NSIG_DRAW:
      271 		dbConsLocate(0,5);
      272 		dbConsPrintf(_T("loading .. %d"), m_load_count);
      273 		return 0;
      274 	}
      275 	return &TaskIco::_stateMemAlloc;
      276 }
      277 
      278 TaskIco::HsmState TaskIco::_stateMain(Event const& e)
      279 {
      280 	switch (e.getSignal()) {
      281 	case Event::NSIG_ENTER:
      282 	case Event::NSIG_RESET_DEVICE:
      283 		_initModel();
      284 		return 0;
      285 	case Event::NSIG_EXIT:
      286 	case Event::NSIG_LOST_DEVICE:
      287 		_releaseModel();
      288 		return 0;
      289 	case Event::NSIG_EXEC:
      290 		// XXX failed to load
      291 		if (!m_pPoly)
      292 			HSM_TRAN(&TaskIco::_stateTerm);
      293 
      294 		m_fAngle += D3DX_PI / EXEC_PER_SEC;
      295 		if ((padGetRep() & (PAD_SE | PAD_ST)) == (PAD_SE | PAD_ST))
      296 			HSM_TRAN(&TaskIco::_stateTerm);
      297 		return 0;
      298 	case Event::NSIG_DRAW:
      299 		_setLight();
      300 		_setCamera();
      301 		_drawModel();
      302 		dbConsLocate(0,5);
      303 		dbConsPrintf(_T("Keep pushing SELECT & START to exit"));
      304 		return 0;
      305 	}
      306 	return &TaskIco::_stateMemAlloc;
      307 }
      308 
      309 TaskIco::HsmState TaskIco::_stateTerm(Event const& /*e*/)
      310 {
      311 	return HSM_TOP();
      312 }
      313 
      314 boost::intrusive_ptr<ITask> CreateTaskIco()
      315 {
      316 	return boost::intrusive_ptr<ITask>(new TaskIco, false);
      317 }
      318