void CFireParticleSystem::Render()
{
	BeforeRender();
	for (int i = 0; i < point_number; i++) {
		if (!fire_particles[i].m_bIsAlive) continue;
		fire_particles[i].Render();
	}
	AfterRender();
}
void Object::Render(const Camera& camera){
	mat4 modelMatrix = BeforeRender();
	mat4 MVPMatrix = camera.projectionMatrix * camera.viewMatrix * modelMatrix;

	glUniformMatrix4fv(camera.MVPMatrixID, 1, GL_FALSE, &MVPMatrix[0][0]);
    
    glDrawArrays(mRenderMode, 0, mNumIndices);	//GL_TRIANGLE_STRIP or GL_TRIANGLES
    
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
}
void LayeredWindowBase::UpdateLayeredWindow()
{
	BeforeRender();
	m_pWin.pAPI->BeginDraw();
	Render();
	if (m_techType == LayeredWindow_TechType_D2DtoGDI)
	{
		m_pWin.pAPI->EndDraw();
		m_info.Update(m_hWnd,m_pWin.pAPI->GetDC());
		m_pWin.pAPI->ReleaseDC();
		
	}
	else
	{
		m_info.Update(m_hWnd,m_pWin.pAPI->GetDC());
		m_pWin.pAPI->ReleaseDC();
		m_pWin.pAPI->EndDraw();
	}
	AfterRender();
}
void Application::Render() {
    BeforeRender();
    AfterRender();
}
LRESULT LayeredWindowBase::WndProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_CREATE:
		//SetTimer(hWnd,1,100,NULL);
		if (Initialize())
			return NULL;
		else
			return -1;

	case WM_SIZE:
		{
			UINT width = LOWORD(lParam);
			UINT height = HIWORD(lParam);
			
			//phLyricsScrollWindow->OnResize(width, height);
			if (width!=0 && height!=0)
			{
				if (SetSize(width,height))
				{
					m_pWin.pAPI->OnSize(width,height);
					RECT rect;
					GetWindowRect(m_hWnd,&rect);
					m_info.m_windowPosition.x = rect.left;
					m_info.m_windowPosition.y = rect.top;
					RedrawWindow(m_hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE);
				}
				printf("WM_SIZE : %d %d -> %d %d\n",width,height,m_pWin.pAPI->GetWidth(),m_pWin.pAPI->GetHeight());

			}

			


			//printf("onSize %d %d\n",width,height);
		}
		return 0;

	case WM_GETMINMAXINFO: //window size/position is going to change
		{
			MINMAXINFO* pInfo = (MINMAXINFO*)lParam;
			pInfo->ptMinTrackSize.x = (long)m_info.m_minsize.cx; //apply custom min width/height
			pInfo->ptMinTrackSize.y = (long)m_info.m_minsize.cy;
		}

		return 0;

	case WM_WINDOWPOSCHANGING:
	case WM_WINDOWPOSCHANGED:
		{
			RECT rect;
			GetWindowRect(m_hWnd,&rect);
			m_info.m_windowPosition.x = rect.left;
			m_info.m_windowPosition.y = rect.top;
		}
		return 0;

	case WM_ACTIVATE:
		UpdateLayeredWindow();
		if (hWnd == m_hWnd)
		{
			
			
				//BeforeRender();
				//m_pWin.pAPI->BeginDraw();
				//Render();
				//m_info.Update(m_hWnd,m_pWin.pAPI->GetDC());
				//m_pWin.pAPI->ReleaseDC();
				//m_pWin.pAPI->EndDraw();
				//AfterRender();
		}
		break;

	case WM_TIMER:
	case WM_PAINT:
	case WM_DISPLAYCHANGE:
		{
			//printf("Render!\n");
			//if (m_vRenderCBList.size())
			//{
			//	//((*m_pRanderCBClass).*m_pRanderCBFunc)();
			//	for (int i=0;i<m_vRenderCBList.size();i++)
			//	{
			//		(m_vRenderCBList[i].pClass->*(m_vRenderCBList[i].pCBFunc))();
			//		//(m_pRanderCBClass->*m_pRanderCBFunc)();
			//	}

			//	
			//}
			//else
			if (hWnd == m_hWnd)
			{
				BeforeRender();
				m_pWin.pAPI->BeginDraw();
				Render();
				m_info.Update(m_hWnd,m_pWin.pAPI->GetDC());
				m_pWin.pAPI->ReleaseDC();
				m_pWin.pAPI->EndDraw();
				AfterRender();
			}


		}
		return 0;

	case WM_DESTROY:
		{
			Uninitialize();
			PostQuitMessage(0);
		}
		return 0;
	case WM_COMMAND:
		break;
	case WM_KEYDOWN:
		//printf("%X key down\n",wParam);
		OnKeyboard(wParam,true);
		break;

	case WM_KEYUP:
		//printf("%X key up\n",wParam);
		OnKeyboard(wParam,false);
		break;

	case WM_MOUSEWHEEL:
	case WM_MOUSEMOVE:
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_LBUTTONDBLCLK:
	case WM_RBUTTONDOWN:
	case WM_RBUTTONUP:
	case WM_RBUTTONDBLCLK:
	case WM_MBUTTONDOWN:
	case WM_MBUTTONUP:
	case WM_MBUTTONDBLCLK:
		{
			
			int x=(short)LOWORD(lParam);
			int y=(short)HIWORD(lParam);
			OnMouse(uMsg,x,y,GET_KEYSTATE_WPARAM(wParam),GET_WHEEL_DELTA_WPARAM(wParam));
			//printf("mouse event : %x @ (%d,%d)\n",uMsg,x,y);
		}
		
		break;

	case WM_NCMOUSEMOVE     :
	case WM_NCLBUTTONDOWN   :
	case WM_NCLBUTTONUP     :
	case WM_NCLBUTTONDBLCLK :
	case WM_NCRBUTTONDOWN   :
	case WM_NCRBUTTONUP     :
	case WM_NCRBUTTONDBLCLK :
	case WM_NCMBUTTONDOWN   :
	case WM_NCMBUTTONUP     :
	case WM_NCMBUTTONDBLCLK :
		{
			int x=(short)LOWORD(lParam);
			int y=(short)HIWORD(lParam);
			OnMouse(uMsg,x,y,0,0);
			//printf("NCmouse event : %x @ (%d,%d)\n",uMsg,x,y);
		}

		break;

	case WM_NCHITTEST:
		{
			//printf("Hit Test : %d\n",DefWindowProc(
			//	//hwnd,
			//	message,
			//	wParam,
			//	lParam
			//	//dwMsgMapID
			//	));
			//break;
			/*
			#define BF_LEFT         0x0001
			#define BF_TOP          0x0002
			#define BF_RIGHT        0x0004
			#define BF_BOTTOM       0x0008
			*/
			
			int x=(short)LOWORD(lParam);
			int y=(short)HIWORD(lParam);
			unsigned char type = 0;
			if (x-m_info.m_windowPosition.x<m_info.m_border)
				type|=BF_LEFT;
			if (y-m_info.m_windowPosition.y<m_info.m_border)
				type|=BF_TOP;
			if (m_info.m_windowPosition.x+m_info.m_size.cx-x<m_info.m_border)
				type|=BF_RIGHT;
			if (m_info.m_windowPosition.y+m_info.m_size.cy-y<m_info.m_border)
				type|=BF_BOTTOM;
			//printf("WM_NCHITTEST (%d,%d): pos (%d,%d)  size (%d,%d)  border %d\n",x,y,m_info.m_windowPosition.x,m_info.m_windowPosition.y,m_info.m_size.cx,m_info.m_size.cy,m_info.m_border);

			switch (type)
			{
			case BF_LEFT:
				return HTLEFT;
				break;
			case BF_RIGHT:
				return HTRIGHT;
				break;
			case BF_TOP:
				return HTTOP;
				break;
			case BF_BOTTOM:
				return HTBOTTOM;
				break;

			case BF_LEFT|BF_TOP:
				return HTTOPLEFT;
				break;
			case BF_LEFT|BF_BOTTOM:
				return HTBOTTOMLEFT;
				break;
			case BF_RIGHT|BF_TOP:
				return HTTOPRIGHT;
				break;
			case BF_RIGHT|BF_BOTTOM:
				return HTBOTTOMRIGHT;
				break;

			default:
				return HTCAPTION;


			}


			
			//printf("hit test : %d\n",res);
			
		}
		return 0;

	case WM_MOVING:
		{
			RECT *pRect = (RECT*)lParam;
			//printf("%d %d\n",pRect->left,pRect->top);
			m_info.m_windowPosition.x = pRect->left;
			m_info.m_windowPosition.y = pRect->top;
		}
		return 0;

	case WM_SIZING:
		{
			RECT *pRect = (RECT*)lParam;
			UINT width = pRect->right-pRect->left;
			UINT height = pRect->bottom-pRect->top;
			bool isMove = true;
			printf("%d %d\n",width,height);
			if (SetSize(width,height))
			{
				m_pWin.pAPI->OnSize(width,height);
				m_info.m_windowPosition.x = pRect->left;
				m_info.m_windowPosition.y = pRect->top;
				printf("WM_SIZING : %d %d -> %d %d\n",width,height,m_pWin.pAPI->GetWidth(),m_pWin.pAPI->GetHeight());
				//Render();
//				m_info.Update(m_hWnd,m_pWin.pAPI->GetDC());
				//m_pWin.pAPI->ReleaseDC();

				UpdateLayeredWindow();
				//m_pWin.pAPI->BeginDraw();
				//Render();
				//m_info.Update(m_hWnd,m_pWin.pAPI->GetDC());
				//m_pWin.pAPI->ReleaseDC();
				//m_pWin.pAPI->EndDraw();
				//RedrawWindow(m_hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE);
			}
			
		}
		return 0;

	default:
		break;
			//printf("msg %X\n",message);
	}
	// Call default window proc if we haven't handled the message
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}