dev.nlited.com

>>

Draw Something!

<<<< prev
next >>>>

2022-12-16 18:56:41 chip Page 2471 📢 PUBLIC

Now that all the resources have been created, I can actually draw something: A simple bouncing ball. It starts with the WM_PAINT message: First I try to create all the DX resources, then update, and finally show. If any of these steps fail, fall back to a simple GDI fill.


MsgPaint(): int PxlShader::MsgPaint(void) { int Err= ERR_OK; PAINTSTRUCT Pnt; GetClientRect(hWnd,&rWnd); if(BeginPaint(hWnd,&Pnt)) { if(IsErr(Err= DrawCreate())) { Err= Warn(Err,"PxlShader:MsgPaint: DrawCreate() failed."); } else if(IsErr(Err= DrawUpdate())) { Err= Warn(Err,"PxlShader:MsgPaint: DrawUdpate() failed."); } else if(IsErr(Err= DrawShow())) { Err= Warn(Err,"PxlShader:MsgPaint: DrawPaint() failed."); } if(IsErr(Err)) { // Fall back to GDI paint. // If I see RED, it means DrawCreate(), DrawUpdate(), or DrawShow() failed. HBRUSH hbrFill= CreateSolidBrush(RGB(255,0,0)); FillRect(Pnt.hdc,&Pnt.rcPaint,hbrFill); DeleteObject(hbrFill); } EndPaint(hWnd,&Pnt); } ValidateRect(hWnd,0); return(1); }

DrawUpdate() draws the scene:

DrawUpdate(): int PxlShader::DrawUpdate(void) { int Err= ERR_OK; HRESULT WinErr; pdcDraw->BeginDraw(); pdcDraw->SetTarget(pbmImg); pdcDraw->Clear(ColorF(ColorF::Black,0)); D2D1_ELLIPSE dot= { ptBall, 50,50 }; pdcDraw->FillEllipse(&dot,D2Brush(pdcDraw,ColorF(ColorF::ForestGreen))); if(!SUCCEEDED(WinErr= pdcDraw->EndDraw())) { Err= Error(ERR_DIRECTX,"PxlShader:DrawUpdate: EndDraw() failed. [%X]",WinErr); ReleaseEverything(); } return(Err); }

DrawShow() flips the SwapChain to show the results. This works because the ID2D1Bitmap that I used in DrawUpdate() was created from the SwapChain().

DrawShow(): int PxlShader::DrawShow(void) { int Err= ERR_OK; HRESULT WinErr; DXGI_PRESENT_PARAMETERS PresentParm; Zero(PresentParm); if(!SUCCEEDED(WinErr= pSwapChain->Present1(1,0,&PresentParm))) { Err= Warn(ERR_DIRECTX,"PxlShader:DrawShow: Present() failed. [%X]",WinErr); } return(Err); }

Finally, I use the WM_TIMER message to move the ball around. Simply invalidating the window will trigger a WM_PAINT message and redrawing everything.

MsgTimer(): int PxlShader::MsgCreate(HWND _hWnd) { hWnd= _hWnd; SetWindowLongPtr(hWnd,GWLP_USERDATA,(LONG_PTR)this); SetTimer(hWnd,1,30,0); return(1); } int PxlShader::MsgTimer(void) { ptBall.x+= BallVector.x; if(ptBall.x < rWnd.left || ptBall.x >= rWnd.right) { BallVector.x= -BallVector.x; ptBall.x+= BallVector.x*2; } ptBall.y+= BallVector.y; if(ptBall.y < rWnd.top || ptBall.y >= rWnd.bottom) { BallVector.y= -BallVector.y; ptBall.y+= BallVector.y*2; } InvalidateRect(hWnd,0,0); return(1); }

Basic Direct2D

I should now be able to watch the ball bounce around the window smoothly. This provides the basic DirectX/Direct2D framework for adding the pixel shader.

PxlShader

I want to make one change before moving on to the gory details of IEffect. The obvious way to move the bouncing ball is to change the center point of the ellipse. However, this means I will need to change the coordinates of everything that is associated with the ball -- not a concern right now, but it will complicate things down the road. Instead, I will create a single Transform matrix, apply the movement to the Transform once, and then let that transform apply automagically to everything else. Now I can always draw the ball in the same position, making the code much simpler and clearer.

Transform: int PxlShader::DrawUpdate(void) { int Err= ERR_OK; HRESULT WinErr; pdcDraw->BeginDraw(); pdcDraw->SetTransform(Matrix3x2F::Identity()); pdcDraw->SetTarget(pbmImg); pdcDraw->Clear(ColorF(ColorF::Black,0)); pdcDraw->SetTransform(Matrix3x2F::Translation(SizeF(ptBall.x,ptBall.y))); D2D1_ELLIPSE dot= { {50,50}, 50,50 }; pdcDraw->FillEllipse(&dot,D2Brush(pdcDraw,ColorF(ColorF::ForestGreen))); if(!SUCCEEDED(WinErr= pdcDraw->EndDraw())) { Err= Error(ERR_DIRECTX,"PxlShader:DrawUpdate: EndDraw() failed. [%X]",WinErr); ReleaseEverything(); } return(Err); }

Moderator: close comments Comments are closed.

Comments are moderated. Anonymous comments are not visible to others until moderated. Comments are owned by the author but may be removed or reused (but not modified) by this site at any time without notice.

HTML
  1. Moderator: [] approve delete HTML



WebV7 (C)2018 nlited | Rendered by tikope in 74.100ms | 18.218.99.80