OSDN Git Service

rm latex/
[moflib/moflib.git] / oldmof / GraphicsDevice.cpp
1
2
3 #include "mof/private/GraphicsDeviceImpl.hpp"
4 #include "mof/ConsoleIO.hpp"
5 #include <list>
6 #include <stdexcept>
7 #include "mof/private/VertexFVF.hpp"
8 #include "mof/Material.hpp"
9 #include "mof/private/TextureImpl.hpp"
10 #include "mof/Window.hpp"
11
12 namespace 
13 {
14         
15         HWND m_hWnd = NULL;
16         int m_width;
17         int m_height;
18         LPDIRECT3DDEVICE9       m_pDevice = NULL;
19         LPDIRECT3D9     m_pD3D = NULL;
20         D3DPRESENT_PARAMETERS* m_pParam = NULL;
21         IDirect3DStateBlock9* m_pNormalBlendingBlock = NULL;
22         IDirect3DStateBlock9* m_pAddBlendingBlock = NULL;
23         IDirect3DStateBlock9* m_pAlphaBlendingBlock = NULL;
24         int m_currentStateBlock;
25         mof::Matrix3D m_worldTransform;
26         mof::Matrix3D m_viewTransform;
27         mof::Matrix3D m_projectionTransform;
28         bool m_flagActive;
29         bool m_flagDeviceLost;
30 }
31
32
33 inline bool isOK(HRESULT hr){
34         return hr == S_OK;
35 }
36
37
38 namespace mof
39 {
40     template void GraphicsDevice::drawVertexArray( const VertexXYZRHWCUV& , const VertexXYZRHWCUV& , PRIMITIVE_TYPE );
41     template void GraphicsDevice::drawVertexArray( const VertexXYZRHWC& , const VertexXYZRHWC& , PRIMITIVE_TYPE);
42     template void GraphicsDevice::drawVertexArray( const VertexXYZCUV& , const VertexXYZCUV& , PRIMITIVE_TYPE);
43     template void GraphicsDevice::drawVertexArray( const VertexXYZNUV& , const VertexXYZNUV& , PRIMITIVE_TYPE);
44     template void GraphicsDevice::drawVertexArray( const VertexXYZC& , const VertexXYZC& , PRIMITIVE_TYPE);
45
46
47
48     //TODO \8aÖ\90\94\95ª\8a\84
49     void GraphicsDevice::initialize( const mof::Window& window , int width , int height , bool fullscreen )
50     {
51     
52             HRESULT     hr;
53             m_hWnd = window.getHandler();
54             m_width = width;
55             m_height = height;
56
57             if( NULL == ( m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
58             {
59                     throw std::runtime_error( "Failed --- Direct3DCreate9" );
60         }
61
62             m_pParam = new D3DPRESENT_PARAMETERS;
63         ZeroMemory( m_pParam, sizeof(D3DPRESENT_PARAMETERS) );
64             m_pParam->Windowed = (fullscreen)? FALSE : TRUE;            //TRUE=Window,FALSE=FULLSCREEN
65             m_pParam->BackBufferCount = 1;
66             m_pParam->PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
67
68             if( fullscreen )
69             {
70                     //\83t\83\8b\83X\83N\83\8a\81[\83\93\8e\9e\82Í\83o\83b\83N\83o\83b\83t\83@\82Ì\95\9d\81A\8d\82\82³\82ð\8dÄ\8ew\92è
71                     m_pParam->BackBufferWidth = width;          //\95\9d
72                     m_pParam->BackBufferHeight = height;                //\8d\82\82³
73                     m_pParam->BackBufferFormat = D3DFMT_X8R8G8B8;       //16bit
74                     //m_pParam->BackBufferFormat = D3DFMT_R5G6B5;       //16bit
75                     m_pParam->FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
76             }
77             else
78             {
79                     m_pParam->BackBufferFormat = D3DFMT_UNKNOWN;        //\8c»\8dÝ\82Ì\89æ\96Ê\83\82\81[\83h\82ð\97\98\97p
80             }
81         m_pParam->SwapEffect = D3DSWAPEFFECT_DISCARD;
82             // Z \83o\83b\83t\83@\82Ì\8e©\93®\8dì\90¬
83             m_pParam->EnableAutoDepthStencil = 1;
84             m_pParam->AutoDepthStencilFormat = D3DFMT_D16;
85     
86
87             
88
89             //HAL(pure vp)
90             if
91             ( 
92                 FAILED
93                 ( 
94                     hr = 
95                     m_pD3D->CreateDevice
96                         (
97                            0 , D3DDEVTYPE_HAL , m_hWnd ,
98                                D3DCREATE_HARDWARE_VERTEXPROCESSING , m_pParam , &m_pDevice
99                             )
100                     )
101                 )
102             {
103                 //HAL(soft vp)
104                 if
105                 (
106                     FAILED
107                     ( 
108                         hr =
109                         m_pD3D->CreateDevice
110                             (
111                                 0 , D3DDEVTYPE_HAL , m_hWnd ,
112                                 D3DCREATE_SOFTWARE_VERTEXPROCESSING , m_pParam , &(m_pDevice) 
113                             )
114                         )
115                     )
116                     {
117                             //REF
118                         if
119                         ( 
120                             FAILED(
121                                 hr = 
122                                 m_pD3D->CreateDevice
123                                 (
124                                     0 , D3DDEVTYPE_REF , m_hWnd ,
125                                         D3DCREATE_HARDWARE_VERTEXPROCESSING , m_pParam , &m_pDevice
126                                     )
127                                 )
128                         )
129                         {
130                                 delete m_pParam;
131                                 m_pD3D->Release();
132                                 throw std::runtime_error(std::string("Failed --- CreateDevice"));
133                             }
134                     } // if
135             } // if
136     
137             setViewport( mof::Rectangle<int>(0 , 0 , width , height) );
138         
139         //
140         m_pDevice->SetSamplerState(0 , D3DSAMP_MAGFILTER , D3DTEXF_LINEAR ); //D3DTEXF_POINT 
141         m_pDevice->SetSamplerState(0 , D3DSAMP_MINFILTER , D3DTEXF_LINEAR ); //D3DTEXF_POINT 
142         
143         
144             m_pDevice->BeginStateBlock( );
145             m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE , TRUE );
146             m_pDevice->SetRenderState( D3DRS_SRCBLEND,D3DBLEND_SRCALPHA );
147             m_pDevice->SetRenderState( D3DRS_DESTBLEND,D3DBLEND_ONE );
148             m_pDevice->SetTextureStageState( 0 , D3DTSS_ALPHAOP,D3DTOP_MODULATE ); //ARG1\82ÆARG2\82Ì\83¿\92l\82ð\8fæ\8eZ\82µ\82Ä\83¿\92l\82ð\8eæ\93¾\82µ\82Ü\82·\81B
149             m_pDevice->SetTextureStageState( 0 , D3DTSS_ALPHAARG1,D3DTA_DIFFUSE ); //\83e\83N\83X\83`\83\83\82Ì\83¿\92l
150             m_pDevice->SetTextureStageState( 0 , D3DTSS_ALPHAARG2,D3DTA_TEXTURE ); //\92¸\93_\82Ì\83¿
151             m_pDevice->SetTextureStageState( 0 , D3DTSS_COLOROP,D3DTOP_MODULATE ); //ARG1\82ÆARG2\82Ì\83J\83\89\81[\82Ì\92l\82ð\8fæ\8eZ\82µ\82Ü\82·\81B
152             m_pDevice->SetTextureStageState( 0 , D3DTSS_COLORARG1,D3DTA_TEXTURE ); //\83e\83N\83X\83`\83\83\82Ì\83J\83\89\81[
153             m_pDevice->SetTextureStageState( 0 , D3DTSS_COLORARG2,D3DTA_DIFFUSE ); //\92¸\93_\82Ì\83J\83\89\81[*/
154             m_pDevice->EndStateBlock( &m_pAddBlendingBlock );
155
156             m_pDevice->BeginStateBlock( );
157             m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE , TRUE );
158             m_pDevice->SetRenderState( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
159             m_pDevice->SetRenderState( D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA );
160         m_pDevice->SetTextureStageState( 0 ,D3DTSS_ALPHAOP , D3DTOP_SELECTARG2 ); //ARG1\82ÆARG2\82Ì\83¿\92l\82ð\8fæ\8eZ\82µ\82Ä\83¿\92l\82ð\8eæ\93¾\82µ\82Ü\82·\81B
161         m_pDevice->SetTextureStageState( 0 ,D3DTSS_ALPHAARG1 , D3DTA_DIFFUSE ); //\83e\83N\83X\83`\83\83\82Ì\83¿\92l
162         m_pDevice->SetTextureStageState( 0 ,D3DTSS_ALPHAARG2 , D3DTA_TEXTURE ); //\92¸\93_\82Ì\83¿\92l
163         m_pDevice->SetTextureStageState( 0 ,D3DTSS_COLOROP , D3DTOP_MODULATE ); //ARG1\82ÆARG2\82Ì\83J\83\89\81[\82Ì\92l\82ð\8fæ\8eZ\82µ\82Ü\82·\81B
164         m_pDevice->SetTextureStageState( 0 ,D3DTSS_COLORARG1 , D3DTA_DIFFUSE ); //\83e\83N\83X\83`\83\83\82Ì\83J\83\89\81[
165         m_pDevice->SetTextureStageState( 0 ,D3DTSS_COLORARG2 , D3DTA_TEXTURE ); //\92¸\93_\82Ì\83J\83\89\81[*/
166         m_pDevice->EndStateBlock( &m_pNormalBlendingBlock );
167
168             m_pDevice->BeginStateBlock( );
169             m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE , TRUE );
170             m_pDevice->SetRenderState( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
171             m_pDevice->SetRenderState( D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA );
172             m_pDevice->SetTextureStageState( 0,D3DTSS_ALPHAOP , D3DTOP_MODULATE ); //ARG1\82ÆARG2\82Ì\83¿\92l\82ð\8fæ\8eZ\82µ\82Ä\83¿\92l\82ð\8eæ\93¾\82µ\82Ü\82·\81B
173             m_pDevice->SetTextureStageState( 0,D3DTSS_ALPHAARG1 , D3DTA_DIFFUSE ); //\83e\83N\83X\83`\83\83\82Ì\83¿\92l
174             m_pDevice->SetTextureStageState( 0,D3DTSS_ALPHAARG2 , D3DTA_TEXTURE ); //\92¸\93_\82Ì\83¿\92l
175             m_pDevice->SetTextureStageState( 0,D3DTSS_COLOROP , D3DTOP_MODULATE ); //ARG1\82ÆARG2\82Ì\83J\83\89\81[\82Ì\92l\82ð\8fæ\8eZ\82µ\82Ü\82·\81B
176             m_pDevice->SetTextureStageState( 0,D3DTSS_COLORARG1 , D3DTA_DIFFUSE ); //\83e\83N\83X\83`\83\83\82Ì\83J\83\89\81[
177             m_pDevice->SetTextureStageState( 0,D3DTSS_COLORARG2 , D3DTA_TEXTURE ); //\92¸\93_\82Ì\83J\83\89\81[*/
178             m_pDevice->EndStateBlock( &m_pAlphaBlendingBlock );
179         
180             setProjectionTransform(0.1f , 100);
181     } // function initialize
182
183
184
185     void GraphicsDevice::finalize( )
186     {
187             m_pAddBlendingBlock->Release();
188             m_pNormalBlendingBlock->Release();
189             m_pAlphaBlendingBlock->Release();
190             if(m_pDevice != NULL)m_pDevice->Release();
191             if(m_pD3D != NULL)m_pD3D->Release();
192             delete m_pParam;
193     }
194
195
196
197
198     void GraphicsDevice::beginScene( )
199     {
200         
201
202             if(true == m_flagDeviceLost)
203             { 
204                 Sleep(100);     // 0.1\95b\91Ò\82Â
205                 if(/*m_flagActive == true &&*/ m_pDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET )
206                 {
207                             //---\83f\83o\83C\83X\95\9c\8bA\82ð\8e\8e\82Ý\82é
208                 
209                         if( FAILED( m_pDevice->Reset( m_pParam) ) )return;
210                                 
211                         //\83f\83o\83C\83X\82Ì\95\9c\8bA\82É\90¬\8c÷
212                         m_flagDeviceLost = false;
213                         //---\83X\83e\81[\83g\82ð\95\9c\8bA
214                         DEBUG_PRINT( "DeviceRecovered!" );
215                     }
216                     else return;
217                 }
218         
219         
220
221             if( !isOK( m_pDevice->BeginScene( ) ) )
222             {
223                 throw std::runtime_error("Failed --- BeginScene");
224             }
225
226
227     } // function beginScene
228         
229
230
231
232     void GraphicsDevice::endScene( )
233     {
234                 
235             if( !isOK( m_pDevice->EndScene() ) )
236             {
237                     throw std::runtime_error("Failed --- EndScene");
238             }
239
240             //\83o\83b\83N\83o\83b\83t\83@\82©\82ç\83v\83\89\83C\83}\83\8a\83o\83b\83t\83@\82Ö\93]\91\97
241             HRESULT hr = m_pDevice->Present( NULL, NULL, NULL, NULL );
242         
243             if( hr == D3DERR_DEVICELOST && false == m_flagDeviceLost )
244             {
245                         DEBUG_PRINT( "DeviceLost!" );
246                         m_flagDeviceLost = true;
247                         //\83\8a\83\\81[\83X\82Ì\89ð\95ú\8f\88\97\9d
248
249                 }
250
251         
252             if( !isOK( hr ) )throw std::runtime_error("Present");
253         
254
255     } // function endScene
256
257
258
259
260     void GraphicsDevice::setWorldTransform( const mof::Matrix3D& matrix )
261     {
262         m_worldTransform = matrix;
263         D3DXMATRIX mat;
264         for(int i = 0 ; i < 4 ; ++i ){
265                 for(int j = 0 ; j < 4 ; ++j){
266                         mat(i , j) = matrix.at(i , j);
267                 }
268         }
269         m_pDevice->SetTransform( D3DTS_WORLD, &mat );
270     }
271
272
273
274     void GraphicsDevice::setProjectionTransform( real min , real max )
275     {
276             D3DXMATRIX matProj;
277             D3DXMatrixPerspectiveFovLH
278             ( 
279                 &matProj, D3DX_PI / 4.0f, 
280                 static_cast<float>(getViewportWidth()) / static_cast<float>(getViewportHeight()) , min, max
281             );
282
283             mof::Matrix3D::Array arry;
284             for(int i = 0 ; i < 4 ; ++i ){
285                 for(int j = 0 ; j < 4 ; ++j){
286                         arry.elements[i][j] = matProj( i , j );
287                 }
288             }
289             m_projectionTransform = mof::Matrix3D( arry );
290             m_pDevice->SetTransform( D3DTS_PROJECTION , &matProj );
291
292     } 
293
294
295
296     void GraphicsDevice::setViewTransform( const mof::Matrix3D& matrix )
297     {
298         m_viewTransform = matrix;
299         D3DXMATRIX mat;
300             for(int i = 0 ; i < 4 ; ++i ){
301                     for(int j = 0 ; j < 4 ; ++j){
302                         mat(i , j) = matrix.at(i , j);
303                     }
304             }
305             m_pDevice->SetTransform( D3DTS_VIEW , &mat );
306     }
307
308
309
310
311     const mof::Matrix3D& GraphicsDevice::getWorldTransform( ) 
312     {
313             return m_worldTransform;
314     }
315
316
317                 
318     const mof::Matrix3D& GraphicsDevice::getProjectionTransform() 
319     {
320             return m_projectionTransform;
321     }
322         
323
324
325     const mof::Matrix3D& GraphicsDevice::getViewTransform()
326     {
327         return m_viewTransform;
328     }
329
330         
331
332     void GraphicsDevice::setZBuffer( bool available )
333     {
334             if( available )m_pDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
335             else m_pDevice->SetRenderState( D3DRS_ZENABLE , D3DZB_FALSE );          
336     }
337
338
339
340     void GraphicsDevice::lightEnable( bool available )
341     {
342             m_pDevice->SetRenderState( D3DRS_LIGHTING , available );
343     }
344
345
346
347     void GraphicsDevice::clearZBuffer()
348     {
349             m_pDevice->Clear( 0 , NULL , D3DCLEAR_ZBUFFER , 0 , 1.0f, 0 );
350     }
351
352
353
354     void GraphicsDevice::clearRenderTarget( mof::Color color )
355     {
356             m_pDevice->Clear( 0 , 0 , D3DCLEAR_TARGET , color ,  0 , 0 );
357     }
358
359
360
361     void GraphicsDevice::setAlphaBlendingMode( const int flag )
362     {
363         if(flag == m_currentStateBlock )return;
364
365         if( flag == mof::GraphicsDevice::BLENDING_MODE_ADD ){
366                 m_pAddBlendingBlock->Apply();
367         }
368             else if(flag == mof::GraphicsDevice::BLENDING_MODE_BASIC)
369             {
370                     m_pNormalBlendingBlock->Apply();
371             }
372             else if( flag == mof::GraphicsDevice::BLENDING_MODE_ALPHA )
373             {
374                     m_pAlphaBlendingBlock->Apply();
375             }
376
377             m_currentStateBlock = flag;
378     }
379
380
381
382     Vector2D GraphicsDevice::to2DPosition( const mof::Vector3D& position )
383     {
384             mof::Matrix3D matrix = m_worldTransform;
385             matrix = m_viewTransform * m_projectionTransform;
386             int hWidth = getViewportWidth() / 2;
387             int hHeight = getViewportHeight() / 2;
388             mof::Vector3D tmpPosition =  position * matrix;
389          
390             return mof::Vector2D
391             (
392                 static_cast<int>(tmpPosition.x * hWidth + hWidth ) , 
393                         static_cast<int>(-tmpPosition.y * hHeight + hHeight)
394                 );
395     }
396
397
398     void GraphicsDevice::setViewport( const mof::Rectangle<int>& area )
399     {
400         D3DVIEWPORT9 vp;
401         vp.X = area.beginX;
402         vp.Y = area.beginY;
403         vp.Width = area.getWidth( );
404         vp.Height = area.getHeight( );
405         vp.MinZ = 0.0f;
406         vp.MaxZ = 1.0f;
407         if( FAILED( m_pDevice->SetViewport( &vp ) ) )
408         {
409                     throw std::runtime_error( "Failed --- SetViewport" );
410             }
411     }
412
413     int GraphicsDevice::getViewportWidth( ) 
414     {
415             D3DVIEWPORT9 vp;
416             if( FAILED(m_pDevice->GetViewport( &vp ) ) )
417             {
418                 throw std::runtime_error("Failed --- getViewportWidth");
419             }
420             return vp.Width;
421     }
422
423
424     int GraphicsDevice::getViewportHeight() {
425             D3DVIEWPORT9 vp;
426             if( FAILED( m_pDevice->GetViewport( &vp ) ) )
427             {
428                 throw std::runtime_error("Failed --- getViewportHeight");
429             }
430             return vp.Height;
431     }
432
433
434
435
436     template <class T>
437     void GraphicsDevice::drawVertexArray( const T& front , const T& last , mof::PRIMITIVE_TYPE type )
438     {
439             HRESULT hr = E_FAIL;
440             if(&last < &front)return;
441             int length = &last - &front + 1; //\92¸\93_\90\94
442
443             m_pDevice->SetFVF( mof::getFVF<T>() );
444
445             if(type == mof::PRIMITIVE_TYPE_TRIANGLESTRIP)
446             {
447                 hr = m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP , length > 3 ? length - 2 : 1 , (const void*)&front , sizeof(T) );
448             }
449         else if( type == PRIMITIVE_TYPE_TRIANGLELIST )
450         {
451                 hr = m_pDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST , length / 3 , (const void*)&front , sizeof(T) );
452             }
453             else if( type == mof::PRIMITIVE_TYPE_LINELIST )
454             {
455                 hr = m_pDevice->DrawPrimitiveUP(D3DPT_LINELIST , length / 2 , (const void*)&front , sizeof(T) );
456         }
457         
458             if( FAILED( hr ) )
459             {
460                     throw std::runtime_error("Failed -- DrawPrimitiveUP");
461             }
462
463     } // function drawVertexArray
464
465
466
467     void GraphicsDevice::setMaterial(const mof::Material& material){
468             D3DMATERIAL9 mat;
469
470             memcpy(static_cast<void*>(&mat) , static_cast<const void*>(&material) , sizeof(D3DMATERIAL9));
471
472             if( FAILED( m_pDevice->SetMaterial( &mat ) ) )
473             {
474                     throw std::runtime_error("Faild --- SetMaterial");
475             }
476     }
477
478
479     void GraphicsDevice::setTexture( const mof::Texture* pTexture )
480     {
481             if( pTexture == NULL )m_pDevice->SetTexture( 0 , NULL );
482             else m_pDevice->SetTexture( 0 , pTexture->m_pImpl->pTexture );
483     }
484
485
486     mof::Rectangle<int> GraphicsDevice::getClientRegion() 
487     {
488         
489
490             RECT rect;
491             GetWindowRect(m_hWnd , &rect);
492             POINT point;
493             point.x = rect.left;
494             point.y = rect.top;
495             ScreenToClient(m_hWnd , &point);
496             int beginX = rect.left - point.x;
497             int beginY = rect.top - point.y;
498             return mof::Rectangle<int>(beginX , beginY , beginX + m_width , beginY + m_height);
499     }
500     
501     LPDIRECT3DDEVICE9 GraphicsDevice::getRawDevice( )
502     {
503         return m_pDevice;
504     }
505     
506 } // namespace GraphicsDevice