LRESULT CALLBACK MyFunc( HWND h, UINT msg, WPARAM w, LPARAM p )
{
	HDC dc;
	PAINTSTRUCT ps;
	int x = ( ( int )( short )LOWORD( p ) ), y = ( ( int )( short )HIWORD( p ) );

	switch ( msg )
	{
		case WM_KEYUP:
			if ( w == 27 ) { SendMessage( h, WM_DESTROY, 0, 0 ); } // OnKeyUp( w );

			break;

		case WM_KEYDOWN:
			OnKeyDown( w );
			break;

		case WM_LBUTTONDOWN:
			SetCapture( h );
			OnMouseDown( 0, x, y );
			break;

		case WM_MOUSEMOVE:
			OnMouseMove( x, y );
			break;

		case WM_LBUTTONUP:
			OnMouseUp( 0, x, y );
			ReleaseCapture();
			break;

		case WM_DESTROY:
			PostQuitMessage( 0 );
			break;

		case WM_PAINT:
			OnDrawFrame();
			dc = BeginPaint( h, &ps );
			// transfer the g_FrameBuffer to the hTmpBmp
			SetDIBits( hMemDC, hTmpBmp, 0, ImageHeight, g_FrameBuffer, &BitmapInfo, DIB_RGB_COLORS );
			SelectObject( hMemDC, hTmpBmp );
			// Copying the offscreen buffer to the window surface
			BitBlt( dc, 0, 0, ImageWidth, ImageHeight, hMemDC, 0, 0, SRCCOPY );
			EndPaint( h, &ps );
			break;

		case WM_TIMER:
			InvalidateRect( h, NULL, 1 );
			break;
	}

	return DefWindowProc( h, msg, w, p );
}
	JNIEXPORT void JNICALL Java_com_packtpub_ndkcookbook_app12_App12Activity_DrawFrame( JNIEnv* env, jobject obj )
	{
		// call our callback
		OnDrawFrame();

		glActiveTexture( GL_TEXTURE0 );
		glBindTexture( GL_TEXTURE_2D, g_Texture );
		glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, ImageWidth, ImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, g_FrameBuffer );

		// render on screen
		GLDebug_RenderTriangle();
	}
void OpenGLRenderForm::OnTimerExpired(Osp::Base::Runtime::Timer & timer) {

	if (isRendering) {
		_timer->Start(TIMER_INTERVAL_MS);

		OnDrawFrame();
    	eglSwapBuffers(eDisplay, eSurface);

    	static float     fps = 0.0f;
    	static float     updateInterval = 1000.0f;
    	static float     timeSinceLastUpdate = 0.0f;
    	static float     frameCount = 0;
    	static long long currentTick;
    	static long long lastTick;
    	static bool      isFirst = true;

    	if (isFirst)
    	{
    		SystemTime::GetTicks(currentTick);
    		lastTick = currentTick;
    		isFirst = false;
    	}

    	frameCount++;
    	SystemTime::GetTicks(currentTick);

    	float elapsed = currentTick - lastTick;

    	lastTick = currentTick;
    	timeSinceLastUpdate += elapsed;

    	if (timeSinceLastUpdate > updateInterval)
    	{
    		if (timeSinceLastUpdate)
    		{
    			fps = (frameCount / timeSinceLastUpdate) * 1000.f;
    			AppLog("FPS: %f frames/sec\n", fps);

    			frameCount = 0;
    			timeSinceLastUpdate -= updateInterval;
    		}
    	}

	}

}
void GenerateTicks()
{
	NewTime = GetSeconds();
	float DeltaSeconds = static_cast<float>( NewTime - OldTime );
	OldTime = NewTime;

	const float TIME_QUANTUM = 0.0166666f;
	const float MAX_EXECUTION_TIME = 10.0f * TIME_QUANTUM;

	ExecutionTime += DeltaSeconds;

	if ( ExecutionTime > MAX_EXECUTION_TIME ) { ExecutionTime = MAX_EXECUTION_TIME; }

	while ( ExecutionTime > TIME_QUANTUM )
	{
		ExecutionTime -= TIME_QUANTUM;
		OnTimer( TIME_QUANTUM );
	}

	OnDrawFrame();
}