D3DMで2D描画(色加算)
Main.cpp
#include <windows.h> #include <d3dm.h.> #include <d3dmx.h> #include "resource.h" #pragma comment(lib, "d3dm.lib") #pragma comment(lib, "d3dmx.lib") LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); #define PROC_NAME L"ProcSample12" bool InitD3dm( HWND ); void ExitD3dm( void ); void Render( void ); //---------------------------------------------------------------- int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPreInst, LPWSTR lpszCmdLine, int nCmdShow ) { HWND hwnd; MSG msg; WNDCLASS myProg; if (!hPreInst) { myProg.style = CS_HREDRAW | CS_VREDRAW; myProg.lpfnWndProc = WndProc; myProg.cbClsExtra = 0; myProg.cbWndExtra = 0; myProg.hInstance = hInstance; myProg.hIcon = NULL; myProg.hCursor = NULL; myProg.hbrBackground = (HBRUSH)COLOR_WINDOW; myProg.lpszMenuName = NULL; myProg.lpszClassName = PROC_NAME; if (!RegisterClass( &myProg )){ return FALSE; } } hwnd = CreateWindow( PROC_NAME, L"Sample12", WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if( InitD3dm( hwnd ) == false ) return FALSE; ShowWindow( hwnd, nCmdShow ); UpdateWindow( hwnd ); do{ if(PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE )) { TranslateMessage( &msg ); DispatchMessage( &msg ); }else{ Render(); } } while(msg.message != WM_QUIT); ExitD3dm(); return (int)( msg.wParam ); } //---------------------------------------------------------------- LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { switch (msg) { case WM_DESTROY: ExitD3dm(); PostQuitMessage( 0 ); break; default: return(DefWindowProc( hwnd, msg, wParam, lParam )); } return (0L); } //================================================================ // #define BALL_MAX 45 struct BALL { FLOAT x,y; FLOAT ax,ay; }; BALL ballData[ BALL_MAX ]; //================================================================ //D3DM 関係 // 頂点配列 struct VERTEX { FLOAT x, y, z; FLOAT rhw; FLOAT u, v; static const DWORD FVF; }; const DWORD VERTEX::FVF = D3DMFVF_XYZRHW_FLOAT | D3DMFVF_TEX1; #define SAFE_RELEASE(o) {if(o){o->Release();o = NULL;}} IDirect3DMobile* gPd3d = NULL; // Direct3Dオブジェクト IDirect3DMobileDevice* gPd3dmDevice = NULL; // Direct3Dデバイス IDirect3DMobileVertexBuffer* gPVB = NULL; // 頂点バッファ IDirect3DMobileTexture* gPTexture = NULL; // テクスチャ //---------------------------------------------------------------- void SetVertecCal( VERTEX *ballVertex, float u, float v ) { ballVertex->u = u; ballVertex->v = v; ballVertex->z = 0.0f; ballVertex->rhw = 1.0f; } //---------------------------------------------------------------- bool InitD3dm( HWND hwnd) { if(!(gPd3d = Direct3DMobileCreate( D3DM_SDK_VERSION ))) return false; D3DMPRESENT_PARAMETERS d3dmpp; memset( &d3dmpp, 0, sizeof(d3dmpp) ); d3dmpp.Windowed = true; // ウィンドウモード d3dmpp.SwapEffect = D3DMSWAPEFFECT_DISCARD; // フォーマット d3dmpp.BackBufferFormat = D3DMFMT_R5G6B5; d3dmpp.EnableAutoDepthStencil = TRUE; d3dmpp.AutoDepthStencilFormat = D3DMFMT_D16; // Zバッファが16bit // デバイスの生成 if( gPd3d->CreateDevice( D3DMADAPTER_DEFAULT, D3DMDEVTYPE_DEFAULT, hwnd, 0, &d3dmpp, &gPd3dmDevice ) != S_OK ) return true; //テクスチャ設定 D3DMCAPS caps; gPd3dmDevice->GetDeviceCaps(&caps); D3DMPOOL texpool; if (caps.SurfaceCaps & D3DMSURFCAPS_VIDTEXTURE){ texpool = D3DMPOOL_VIDEOMEM; // VRAM }else{ texpool = D3DMPOOL_SYSTEMMEM; // システムRAM } if( FAILED( D3DMXCreateTextureFromResourceEx( gPd3dmDevice, GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP1), D3DMX_DEFAULT, D3DMX_DEFAULT, 1, 0, D3DMFMT_UNKNOWN, texpool, D3DMX_FILTER_POINT, D3DMX_FILTER_POINT, 0, NULL, NULL, &gPTexture ) ) ){ return false; } //------------------------------------------- gPd3dmDevice->SetRenderState( D3DMRS_LIGHTING, FALSE ); //ライトOFF gPd3dmDevice->SetRenderState( D3DMRS_CULLMODE, D3DMCULL_NONE ); //両面 //------------------------------------------- int i; D3DMPOOL vbpool; vbpool = D3DMPOOL_SYSTEMMEM; VERTEX *ballVertex; // 頂点バッファの作成 if(FAILED(gPd3dmDevice->CreateVertexBuffer( sizeof(VERTEX)*BALL_MAX*6, 0, VERTEX::FVF, vbpool, &gPVB ))) return false; if(FAILED(gPVB->Lock( 0, 0, (void**)&ballVertex, 0))) return false; for( i = 0 ; i < BALL_MAX ; i++ ){ SetVertecCal( ballVertex++, 0.0f, 0.0f ); SetVertecCal( ballVertex++, 1.0f, 0.0f ); SetVertecCal( ballVertex++, 1.0f, 1.0f ); SetVertecCal( ballVertex++, 0.0f, 0.0f ); SetVertecCal( ballVertex++, 1.0f, 1.0f ); SetVertecCal( ballVertex++, 0.0f, 1.0f ); } gPVB->Unlock(); for( i = 0 ; i < BALL_MAX ; i++ ){ ballData[ i ].x = rand()*400.0f/32767.0f; ballData[ i ].y = rand()*600.0f/32767.0f; ballData[ i ].ax = rand()*8.0f/32767.0f-4.0f; ballData[ i ].ay = rand()*8.0f/32767.0f-4.0f; } return true; } //---------------------------------------------------------------- void ExitD3dm() { SAFE_RELEASE( gPTexture ); SAFE_RELEASE( gPVB ); SAFE_RELEASE( gPd3dmDevice ); SAFE_RELEASE( gPd3d ); } //---------------------------------------------------------------- // BALL計算 void BallCal( BALL *ball ) { ball->x += ball->ax; ball->y += ball->ay; if( ball->x < 2 || ball->x > 400 ) ball->ax = -ball->ax; if( ball->y < 2 || ball->y > 600 ) ball->ay = -ball->ay; } //---------------------------------------------------------------- //頂点登録 void VertecCal( VERTEX *ballVertex, float x, float y ) { //---------------------------- ballVertex->x = x; ballVertex->y = y; ballVertex++; ballVertex->x = x+128; ballVertex->y = y; ballVertex++; ballVertex->x = x+128; ballVertex->y = y+128; ballVertex++; //---------------------------- ballVertex->x = x; ballVertex->y = y; ballVertex++; ballVertex->x = x+128; ballVertex->y = y+128; ballVertex++; ballVertex->x = x; ballVertex->y = y+128; } //---------------------------------------------------------------- void Render() { VERTEX *ballVertex; int i; //BALL計算 for( i = 0 ; i < BALL_MAX ; i++ ) BallCal( &ballData[ i ] ); //BALL頂点登録 gPVB->Lock( 0, 0, (void**)&ballVertex, 0); for( i = 0 ; i < BALL_MAX ; i++ ){ VertecCal( ballVertex, ballData[ i ].x, ballData[ i ].y ); ballVertex +=6; } gPVB->Unlock(); // バックバッファとZバッファのクリア gPd3dmDevice->Clear(0, NULL, D3DMCLEAR_TARGET | D3DMCLEAR_ZBUFFER, D3DMCOLOR_XRGB(0,0,0), 1.0f, 0); // 描画開始 if(SUCCEEDED(gPd3dmDevice->BeginScene())) { //ブレンディング設定 gPd3dmDevice->SetRenderState(D3DMRS_ALPHABLENDENABLE, TRUE); gPd3dmDevice->SetRenderState(D3DMRS_SRCBLEND, D3DMBLEND_SRCCOLOR); gPd3dmDevice->SetRenderState(D3DMRS_DESTBLEND,D3DMBLEND_ONE); // テクスチャ設定 gPd3dmDevice->SetTexture( 0, gPTexture ); // 頂点バッファからレンダリング gPd3dmDevice->SetStreamSource(0, gPVB, sizeof(VERTEX)); gPd3dmDevice->DrawPrimitive(D3DMPT_TRIANGLELIST, 0, BALL_MAX * 2); gPd3dmDevice->SetTexture( 0, NULL ); gPd3dmDevice->EndScene(); } // スクリーンへの転送 gPd3dmDevice->Present(NULL, NULL, NULL, NULL); }
テクスチャはこれを使用しました。(BMPファイル、アルファなし)
■これを実行すると、こんな感じ
エミュレータでは遅くてしょうがないのですが、T01Aではサクサクうごくからいいですかね