void PhysicsDebugSystem::mainUpdate(float elapsedTime)
		{
			if (GetMainThread()->isRenderFrame() == false)
			{
				return;
			}

			//const Physics::DebugInformation &information = _scene->getInstance<Physics::PhysicsInterface>()->getWorld()->getDebugInformation();

			//auto debugManager = GetEngine()->getInstance<DebugDrawManager>();
			//AGE_ASSERT(debugManager);

			//for (const Physics::DebugInformation::Point &point : information.points)
			//{
			//	debugManager->draw3DLine(point.position[0], point.color[0], point.position[0], point.color[0], false);
			//}
			//for (const Physics::DebugInformation::Line &line : information.lines)
			//{
			//	debugManager->draw3DLine(line.position[0], line.color[0], line.position[1], line.color[1], false);
			//}
			//for (const Physics::DebugInformation::Triangle &triangle : information.triangles)
			//{
			//	debugManager->draw3DLine(triangle.position[0], triangle.color[0], triangle.position[1], triangle.color[1], false);
			//	debugManager->draw3DLine(triangle.position[1], triangle.color[1], triangle.position[2], triangle.color[2], false);
			//	debugManager->draw3DLine(triangle.position[2], triangle.color[2], triangle.position[0], triangle.color[0], false);
			//}
		}
void
PeerConnectionMedia::OnCandidateFound_s(NrIceMediaStream *aStream,
                                        const std::string &aCandidateLine)
{
  ASSERT_ON_THREAD(mSTSThread);
  MOZ_ASSERT(aStream);
  MOZ_RELEASE_ASSERT(mIceCtxHdlr);

  CSFLogDebug(logTag, "%s: %s", __FUNCTION__, aStream->name().c_str());

  NrIceCandidate candidate;
  NrIceCandidate rtcpCandidate;
  GetDefaultCandidates(*aStream, &candidate, &rtcpCandidate);

  // ShutdownMediaTransport_s has not run yet because it unhooks this function
  // from its signal, which means that SelfDestruct_m has not been dispatched
  // yet either, so this PCMedia will still be around when this dispatch reaches
  // main.
  GetMainThread()->Dispatch(
    WrapRunnable(this,
                 &PeerConnectionMedia::OnCandidateFound_m,
                 aCandidateLine,
                 candidate.cand_addr.host,
                 candidate.cand_addr.port,
                 rtcpCandidate.cand_addr.host,
                 rtcpCandidate.cand_addr.port,
                 aStream->GetLevel()),
    NS_DISPATCH_NORMAL);
}
	void DebugSystem::mainUpdate(float time)
	{
#if defined(AGE_ENABLE_IMGUI)
		ImGui::Text("Point light number : %i", _pointLights.getCollection().size());

		if (ImGui::SliderFloat("Time multiplier", &_timeMultiplier, 0.0f, 10.0f))
		{
			GetEngine()->setTimeMultiplier(_timeMultiplier);
		}

		static bool hasPhysics = _scene->getSystem<AGE::PhysicsSystem>() == nullptr ? true : false;
		if (ImGui::Checkbox("Physics activated", &hasPhysics))
		{
			if (hasPhysics)
			{
				_scene->activateSystem<AGE::PhysicsSystem>();
			}
			else
			{
				_scene->deactivateSystem<AGE::PhysicsSystem>();
			}
		}
		ImGui::Separator();
		ImGui::Text("Options : applied after relaunch.");
		auto context = _scene->getInstance<IRenderContext>();
		if (ImGui::Checkbox("Fullscreen", &_fullscreen))
		{
			_scene->getInstance<ConfigurationManager>()->setValue<bool>(std::string("fullScreen"), _fullscreen);
		}
		if (ImGui::SliderInt("Window width", &_windowWidth, 800, 1920))
		{
			_scene->getInstance<ConfigurationManager>()->setValue<int>(std::string("windowW"), _windowWidth);
		}
		if (ImGui::SliderInt("Window height", &_windowHeight, 600, 1080))
		{
			_scene->getInstance<ConfigurationManager>()->setValue<int>(std::string("windowH"), _windowHeight);
		}
		static int frameCap = _frameCap;
		bool changeFrameCap = false;
		if (ImGui::RadioButton("30 fps", &frameCap, 1000000 / 30))
			changeFrameCap = true;
		ImGui::SameLine();
		if (ImGui::RadioButton("60 fps", &frameCap, 1000000 / 60))
			changeFrameCap = true;
		ImGui::SameLine();
		if (ImGui::RadioButton("120 fps", &frameCap, 1000000 / 120))
			changeFrameCap = true;
		ImGui::SameLine();
		if (ImGui::RadioButton("Max fps", &frameCap, 0))
			changeFrameCap = true;
		if (changeFrameCap)
		{
			GetMainThread()->setFrameCap(frameCap);
			_scene->getInstance<ConfigurationManager>()->setValue<size_t>(std::string("frameCap"), frameCap);
		}

#endif
	}
void
PeerConnectionMedia::DtlsConnected_s(TransportLayer *layer,
                                     TransportLayer::State state)
{
  MOZ_ASSERT(layer->id() == "dtls");
  TransportLayerDtls* dtlsLayer = static_cast<TransportLayerDtls*>(layer);
  dtlsLayer->SignalStateChange.disconnect(this);

  bool privacyRequested = (dtlsLayer->GetNegotiatedAlpn() == "c-webrtc");
  GetMainThread()->Dispatch(
    WrapRunnableNM(&PeerConnectionMedia::DtlsConnected_m,
                   mParentHandle, privacyRequested),
    NS_DISPATCH_NORMAL);
}
void
PeerConnectionMedia::EndOfLocalCandidates(const std::string& aDefaultAddr,
                                          uint16_t aDefaultPort,
                                          const std::string& aDefaultRtcpAddr,
                                          uint16_t aDefaultRtcpPort,
                                          uint16_t aMLine) {
  // We will still be around because we have not started teardown yet
  GetMainThread()->Dispatch(
    WrapRunnable(this,
                 &PeerConnectionMedia::EndOfLocalCandidates_m,
                 aDefaultAddr, aDefaultPort,
                 aDefaultRtcpAddr, aDefaultRtcpPort, aMLine),
    NS_DISPATCH_NORMAL);
}
Exemple #6
0
void
PeerConnectionMedia::DtlsConnected_s(TransportLayer *dtlsLayer,
                                     TransportLayer::State state)
{
  dtlsLayer->SignalStateChange.disconnect(this);

  bool privacyRequested = false;
  // TODO (Bug 952678) set privacy mode, ask the DTLS layer about that
  // This has to be a dispatch to a static method, we could be going away
  GetMainThread()->Dispatch(
    WrapRunnableNM(&PeerConnectionMedia::DtlsConnected_m,
                   mParentHandle, privacyRequested),
    NS_DISPATCH_NORMAL);
}
void
PeerConnectionMedia::IceGatheringStateChange_s(NrIceCtx* ctx,
                                               NrIceCtx::GatheringState state)
{
  ASSERT_ON_THREAD(mSTSThread);

  if (state == NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
    // Fire off EndOfLocalCandidates for each stream
    for (size_t i = 0; ; ++i) {
      RefPtr<NrIceMediaStream> stream(ctx->GetStream(i));
      if (!stream) {
        break;
      }

      NrIceCandidate candidate;
      nsresult res = stream->GetDefaultCandidate(1, &candidate);
      NrIceCandidate rtcpCandidate;
      // Optional; component won't exist if doing rtcp-mux
      if (NS_FAILED(stream->GetDefaultCandidate(2, &rtcpCandidate))) {
        rtcpCandidate.cand_addr.host.clear();
        rtcpCandidate.cand_addr.port = 0;
      }
      if (NS_SUCCEEDED(res)) {
        EndOfLocalCandidates(candidate.cand_addr.host,
                             candidate.cand_addr.port,
                             rtcpCandidate.cand_addr.host,
                             rtcpCandidate.cand_addr.port,
                             i);
      } else {
        CSFLogError(logTag, "%s: GetDefaultCandidate failed for level %u, "
                            "res=%u",
                            __FUNCTION__,
                            static_cast<unsigned>(i),
                            static_cast<unsigned>(res));
      }
    }
  }

  // ShutdownMediaTransport_s has not run yet because it unhooks this function
  // from its signal, which means that SelfDestruct_m has not been dispatched
  // yet either, so this PCMedia will still be around when this dispatch reaches
  // main.
  GetMainThread()->Dispatch(
    WrapRunnable(this,
                 &PeerConnectionMedia::IceGatheringStateChange_m,
                 ctx,
                 state),
    NS_DISPATCH_NORMAL);
}
void
PeerConnectionMedia::IceConnectionStateChange_s(NrIceCtx* ctx,
                                                NrIceCtx::ConnectionState state)
{
  ASSERT_ON_THREAD(mSTSThread);
  // ShutdownMediaTransport_s has not run yet because it unhooks this function
  // from its signal, which means that SelfDestruct_m has not been dispatched
  // yet either, so this PCMedia will still be around when this dispatch reaches
  // main.
  GetMainThread()->Dispatch(
    WrapRunnable(this,
                 &PeerConnectionMedia::IceConnectionStateChange_m,
                 ctx,
                 state),
    NS_DISPATCH_NORMAL);
}
void
PeerConnectionMedia::EndOfLocalCandidates(const std::string& aDefaultAddr,
                                          uint16_t aDefaultPort,
                                          const std::string& aDefaultRtcpAddr,
                                          uint16_t aDefaultRtcpPort,
                                          uint16_t aMLine)
{
  GetMainThread()->Dispatch(
    WrapRunnable(this,
                 &PeerConnectionMedia::EndOfLocalCandidates_m,
                 aDefaultAddr,
                 aDefaultPort,
                 aDefaultRtcpAddr,
                 aDefaultRtcpPort,
                 aMLine),
    NS_DISPATCH_NORMAL);
}
	void ArchetypeManager::loadOne(const std::string &name)
	{
		if (_archetypesCollection.find(name) != std::end(_archetypesCollection))
		{
			return;
		}

		auto currentScene = GetMainThread()->getActiveScene();

		auto path = _libraryFolder + "/" + name + ".archetype";
		BinaryEntityPack pack;
		pack.scene = getScene();

		pack.loadFromFile(path);

		auto &entity = pack.entities.front().entity;
		_archetypesCollection.insert(std::make_pair(name, entity));
	}
/*
    Función: DllMain
    Descripción: 
        En la carga de la DLL solo lanzamos un hilo para controlar las llamadas
        a la consola.
    Parametros: 
        hInst           - Manejador de la biblioteca
        reason          - Razon por la que llama a esta funcion
        reserved        - Valor usado internamente
    Retorno: 
        FALSE           - Fallo en alguno de los pasos del proceso
        TRUE            - Funcionamiento correcto del proceso
*/
BOOL 
APIENTRY 
DllMain ( HINSTANCE hInst, DWORD reason, LPVOID reserved )
{
    // Variables locales
    WSADATA         wsaData;
    DWORD           tid;  
    
    tid = 0;          
        
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
            // Obtenemos un handle al hilo principal
            MainThread = GetMainThread();                    
        
            // Inicializamos las conexiones por sockets
            if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)             
                MessageBoxA( NULL, "WSAStartup", "error", MB_OK );            
            else          
                // Creamos el hilo que controlara la consola
                CreateThread
                ( 
                    NULL                                , 
                    0                                   , 
                    (LPTHREAD_START_ROUTINE) LoadConsole, 
                    NULL                                , 
                    0                                   , 
                    & tid 
                );                    
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    return TRUE;
}
void
PeerConnectionMedia::IceGatheringStateChange_s(NrIceCtx* ctx,
                                               NrIceCtx::GatheringState state)
{
  ASSERT_ON_THREAD(mSTSThread);

  if (state == NrIceCtx::ICE_CTX_GATHER_COMPLETE) {
    // Fire off EndOfLocalCandidates for each stream
    for (size_t i = 0; ; ++i) {
      RefPtr<NrIceMediaStream> stream(ctx->GetStream(i));
      if (!stream) {
        break;
      }

      NrIceCandidate candidate;
      NrIceCandidate rtcpCandidate;
      GetDefaultCandidates(*stream, &candidate, &rtcpCandidate);
      EndOfLocalCandidates(candidate.cand_addr.host,
                           candidate.cand_addr.port,
                           rtcpCandidate.cand_addr.host,
                           rtcpCandidate.cand_addr.port,
                           i);
    }
  }

  // ShutdownMediaTransport_s has not run yet because it unhooks this function
  // from its signal, which means that SelfDestruct_m has not been dispatched
  // yet either, so this PCMedia will still be around when this dispatch reaches
  // main.
  GetMainThread()->Dispatch(
    WrapRunnable(this,
                 &PeerConnectionMedia::IceGatheringStateChange_m,
                 ctx,
                 state),
    NS_DISPATCH_NORMAL);
}
	void RenderCameraSystem::mainUpdate(float time)
	{
		SCOPE_profile_cpu_function("Camera system");
		_scene->getBfcLinkTracker()->reset();

		// check if the render thread does not already have stuff to draw
		if (GetMainThread()->isRenderFrame() == false)
		{
			return;
		}

		std::list<std::shared_ptr<DRBSpotLightDrawableList>> spotLightList;
		std::list<std::shared_ptr<DRBData>> pointLightList;


		for (auto &spotEntity : _spotLights.getCollection())
		{
			auto spot = spotEntity->getComponent<SpotLightComponent>();
			auto spotDrawableList = std::make_shared<DRBSpotLightDrawableList>();
			spotDrawableList->spotLight = spot->getCullableHandle().getPtr()->getDatas();

			auto spotData = std::static_pointer_cast<DRBSpotLightData>(spotDrawableList->spotLight);

			glm::mat4 spotViewProj = spot->updateShadowMatrix();

			Frustum spotlightFrustum;
			spotlightFrustum.setMatrix(spotViewProj);

			// Draw spotlight frustum debug:
			glm::vec4 worldPos = glm::inverse(spotViewProj) * glm::vec4(-1, -1, -1, 1.0f);
			glm::vec3 aNear = glm::vec3(worldPos / worldPos.w);
			worldPos = glm::inverse(spotViewProj) * glm::vec4(-1, 1, -1, 1.0f);
			glm::vec3 bNear = glm::vec3(worldPos / worldPos.w);
			worldPos = glm::inverse(spotViewProj) * glm::vec4(1, 1, -1, 1.0f);
			glm::vec3 cNear = glm::vec3(worldPos / worldPos.w);
			worldPos = glm::inverse(spotViewProj) * glm::vec4(1, -1, -1, 1.0f);
			glm::vec3 dNear = glm::vec3(worldPos / worldPos.w);
			worldPos = glm::inverse(spotViewProj) * glm::vec4(-1, -1, 1, 1.0f);
			glm::vec3 aFar = glm::vec3(worldPos / worldPos.w);
			worldPos = glm::inverse(spotViewProj) * glm::vec4(-1, 1, 1, 1.0f);
			glm::vec3 bFar = glm::vec3(worldPos / worldPos.w);
			worldPos = glm::inverse(spotViewProj) * glm::vec4(1, 1, 1, 1.0f);
			glm::vec3 cFar = glm::vec3(worldPos / worldPos.w);
			worldPos = glm::inverse(spotViewProj) * glm::vec4(1, -1, 1, 1.0f);
			glm::vec3 dFar = glm::vec3(worldPos / worldPos.w);

			glm::vec3 color = glm::vec3(1, 0, 0);
			bool activateDepth = true;

			if (_drawDebugLines)
			{
				AGE::GetRenderThread()->getQueue()->emplaceTask<Commands::ToRender::Draw3DQuad>(aNear, bNear, cNear, dNear, color, activateDepth);
				AGE::GetRenderThread()->getQueue()->emplaceTask<Commands::ToRender::Draw3DQuad>(aFar, bFar, cFar, dFar, color, activateDepth);
				AGE::GetRenderThread()->getQueue()->emplaceTask<Commands::ToRender::Draw3DLine>(aNear, aFar, color, activateDepth);
				AGE::GetRenderThread()->getQueue()->emplaceTask<Commands::ToRender::Draw3DLine>(bNear, bFar, color, activateDepth);
				AGE::GetRenderThread()->getQueue()->emplaceTask<Commands::ToRender::Draw3DLine>(cNear, cFar, color, activateDepth);
				AGE::GetRenderThread()->getQueue()->emplaceTask<Commands::ToRender::Draw3DLine>(dNear, dFar, color, activateDepth);
			}

			std::atomic_size_t counter = 0;

			LFList<BFCItem> meshInLightList;
			std::size_t meshBlocksToCullNumber = _scene->getBfcBlockManagerFactory()->getBlockNumberToCull(BFCCullableType::CullableMesh);

			for (std::size_t i = 0; i < meshBlocksToCullNumber; ++i)
			{
				BFCBlockManagerFactory *bf = _scene->getBfcBlockManagerFactory();
				EmplaceTask<Tasks::Basic::VoidFunction>([bf, i, &spotlightFrustum, &counter, &meshInLightList](){
					bf->cullOnBlock(BFCCullableType::CullableMesh, meshInLightList, spotlightFrustum, i);
					counter.fetch_add(1);
				});
			}

			{
				SCOPE_profile_cpu_i("Camera system", "Cull for spots");
				while (counter < meshBlocksToCullNumber )
				{
				}
				//GetMainThread()->computeTasksWhile(std::function<bool()>([&counter, meshBlocksToCullNumber]() {
				//	return counter >= meshBlocksToCullNumber;
				//}));
			}

			while (meshInLightList.getSize() > 0)
			{
				spotDrawableList->meshs.push_back(meshInLightList.pop()->getDrawable()->getDatas());
			}

			spotLightList.push_back(spotDrawableList);
		}
		for (auto &pointLightEntity : _pointLights.getCollection())
		{
			auto point = pointLightEntity->getComponent<PointLightComponent>();
			
			pointLightList.push_back(point->getCullableHandle().getPtr()->getDatas());
		}

		for (auto &cameraEntity : _cameras.getCollection())
		{
			Frustum cameraFrustum;
			auto camera = cameraEntity->getComponent<CameraComponent>();

			std::atomic_size_t counter = 0;

			auto cameraList = std::make_shared<DRBCameraDrawableList>();
			cameraList->cameraInfos.data = camera->getData();
			cameraList->cameraInfos.view = glm::inverse(cameraEntity->getLink().getGlobalTransform());

			cameraFrustum.setMatrix(camera->getProjection() * cameraList->cameraInfos.view);

			LFList<BFCItem> meshList;
			LFList<BFCItem> pointLightListToCull;
			std::size_t meshBlocksToCullNumber = _scene->getBfcBlockManagerFactory()->getBlockNumberToCull(BFCCullableType::CullableMesh);
			std::size_t pointLightBlocksToCullNumber = _scene->getBfcBlockManagerFactory()->getBlockNumberToCull(BFCCullableType::CullablePointLight);
			std::size_t totalToCullNumber = meshBlocksToCullNumber + pointLightBlocksToCullNumber;
			
			for (std::size_t i = 0; i < meshBlocksToCullNumber; ++i)
			{
				BFCBlockManagerFactory *bf = _scene->getBfcBlockManagerFactory();
				EmplaceTask<Tasks::Basic::VoidFunction>([bf, i, &cameraFrustum, &counter, &meshList](){
					bf->cullOnBlock(BFCCullableType::CullableMesh, meshList, cameraFrustum, i);
					counter.fetch_add(1);
				});
			}

			for (std::size_t i = 0; i < pointLightBlocksToCullNumber; ++i)
			{
				BFCBlockManagerFactory *bf = _scene->getBfcBlockManagerFactory();
				EmplaceTask<Tasks::Basic::VoidFunction>([bf, i, &cameraFrustum, &counter, &pointLightListToCull](){
					bf->cullOnBlock(BFCCullableType::CullablePointLight, pointLightListToCull, cameraFrustum, i);
					counter.fetch_add(1);
				});
			}

			{
				SCOPE_profile_cpu_i("Camera system", "Cull for cam");
				while (counter < totalToCullNumber)
				{ }
				//GetMainThread()->computeTasksWhile(std::function<bool()>([&counter, totalToCullNumber]() {
				//	return counter >= totalToCullNumber;
				//}));
			}

			{
				SCOPE_profile_cpu_i("Camera system", "Copy LFList to std");
				while (meshList.getSize() > 0)
				{
					cameraList->meshs.push_back(meshList.pop()->getDrawable()->getDatas());
				}

				while (pointLightListToCull.getSize() > 0)
				{
					cameraList->pointLights.push_back(pointLightListToCull.pop()->getDrawable()->getDatas());
				}
			}
			if (OcclusionConfig::g_Occlusion_is_enabled)
			{
				occlusionCulling(cameraList->meshs, _drawDebugLines);
			}

			cameraList->spotLights = spotLightList;
			cameraList->pointLights = pointLightList;
			AGE::GetRenderThread()->getQueue()->emplaceTask<AGE::DRBCameraDrawableListCommand>(cameraList);
		}
	}
Exemple #14
0
	bool Imgui::init(Engine *en)
	{
#ifdef AGE_ENABLE_IMGUI

		GetMainThread()->registerCallback<ImGuiKeyEvent>([this](ImGuiKeyEvent &msg)
		{
			ImGuiIO& io = ImGui::GetIO();
			io.KeysDown[int(msg.key)] = msg.down;
			if (msg.key == AgeKeys::AGE_LCTRL || msg.key == AgeKeys::AGE_RCTRL)
				io.KeyCtrl = msg.down;
			else if (msg.key == AgeKeys::AGE_LSHIFT || msg.key == AgeKeys::AGE_RSHIFT)
				io.KeyShift = msg.down;
			else if (msg.down)
			{
				char character = keyToAscii.find(msg.key)->second;
				if (character != UNDEFINED_CHARACTER)
					io.AddInputCharacter(character);
			}
		});

		GetMainThread()->registerCallback<ImGuiEndOfFrame>([this](ImGuiEndOfFrame &msg)
		{
			SCOPE_profile_cpu_i("ImGui", "Render");
			ImGui::Render();
		});

		GetMainThread()->registerCallback<ImGuiMouseStateEvent>([this](ImGuiMouseStateEvent &msg)
		{
			_lastMouseState = msg;
		});

		_engine = en;
		//HARDCODED WINDOW TO FIX
		//auto window = di->getInstance<AGE::Threads::Render>()->getCommandQueue()->safePriorityFutureEmplace<RendCtxCommand::GetScreenSize, glm::uvec2>().get();

		ImGuiIO& io = ImGui::GetIO();
		//HARDCODED WINDOW TO FIX
		auto screenSize = en->getInstance<IRenderContext>()->getScreenSize();
		io.DisplaySize = ImVec2((float)screenSize.x, (float)screenSize.y);        // Display size, in pixels. For clamping windows positions.
		io.DeltaTime = 1.0f / 60.0f;                          // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our timestep is variable)
		io.KeyMap[ImGuiKey_Tab] = int(AgeKeys::AGE_TAB);             // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array.
		io.KeyMap[ImGuiKey_LeftArrow] =  int(AgeKeys::AGE_LEFT);
		io.KeyMap[ImGuiKey_RightArrow] = int(AgeKeys::AGE_RIGHT);
		io.KeyMap[ImGuiKey_UpArrow] =    int(AgeKeys::AGE_UP);
		io.KeyMap[ImGuiKey_DownArrow] =  int(AgeKeys::AGE_DOWN);
		io.KeyMap[ImGuiKey_Home] =       int(AgeKeys::AGE_HOME);
		io.KeyMap[ImGuiKey_End] =        int(AgeKeys::AGE_END);
		io.KeyMap[ImGuiKey_Delete] =     int(AgeKeys::AGE_DELETE);
		io.KeyMap[ImGuiKey_Backspace] =  int(AgeKeys::AGE_BACKSPACE);
		io.KeyMap[ImGuiKey_Enter] =      int(AgeKeys::AGE_RETURN);
		io.KeyMap[ImGuiKey_Escape] =     int(AgeKeys::AGE_ESCAPE);
		io.KeyMap[ImGuiKey_A] =          int(AgeKeys::AGE_a);
		io.KeyMap[ImGuiKey_C] =          int(AgeKeys::AGE_c);
		io.KeyMap[ImGuiKey_V] =          int(AgeKeys::AGE_v);
		io.KeyMap[ImGuiKey_X] =          int(AgeKeys::AGE_x);
		io.KeyMap[ImGuiKey_Y] =          int(AgeKeys::AGE_y);
		io.KeyMap[ImGuiKey_Z] =          int(AgeKeys::AGE_z);

		io.RenderDrawListsFn = renderDrawLists;

		//io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
		//io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;

		const GLchar *vertex_shader =
			"#version 330\n"
			"uniform mat4 ProjMtx;\n"
			"in vec2 Position;\n"
			"in vec2 UV;\n"
			"in vec4 Color;\n"
			"out vec2 Frag_UV;\n"
			"out vec4 Frag_Color;\n"
			"void main()\n"
			"{\n"
			"	Frag_UV = UV;\n"
			"	Frag_Color = Color;\n"
			"	gl_Position = ProjMtx * vec4(Position.xy,0,1);\n"
			"}\n";

		const GLchar* fragment_shader =
			"#version 330\n"
			"uniform sampler2D Texture;\n"
			"in vec2 Frag_UV;\n"
			"in vec4 Frag_Color;\n"
			"out vec4 Out_Color;\n"
			"void main()\n"
			"{\n"
			"	Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n"
			"}\n";

		shader_handle = glCreateProgram();
		vert_handle = glCreateShader(GL_VERTEX_SHADER);
		frag_handle = glCreateShader(GL_FRAGMENT_SHADER);
		glShaderSource(vert_handle, 1, &vertex_shader, 0);
		glShaderSource(frag_handle, 1, &fragment_shader, 0);
		glCompileShader(vert_handle);
		glCompileShader(frag_handle);
		glAttachShader(shader_handle, vert_handle);
		glAttachShader(shader_handle, frag_handle);
		glLinkProgram(shader_handle);

		texture_location = glGetUniformLocation(shader_handle, "Texture");
		ortho_location = glGetUniformLocation(shader_handle, "ProjMtx");
		position_location = glGetAttribLocation(shader_handle, "Position");
		uv_location = glGetAttribLocation(shader_handle, "UV");
		colour_location = glGetAttribLocation(shader_handle, "Color");

		glGenBuffers(1, &vbo_handle);
		glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
		glBufferData(GL_ARRAY_BUFFER, vbo_max_size, NULL, GL_DYNAMIC_DRAW);

		glGenVertexArrays(1, &vao_handle);
		glBindVertexArray(vao_handle);
		glBindBuffer(GL_ARRAY_BUFFER, vbo_handle);
		glEnableVertexAttribArray(position_location);
		glEnableVertexAttribArray(uv_location);
		glEnableVertexAttribArray(colour_location);

		glVertexAttribPointer(position_location, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, pos));
		glVertexAttribPointer(uv_location, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, uv));
		glVertexAttribPointer(colour_location, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)OFFSETOF(ImDrawVert, col));
		glBindVertexArray(0);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		// Load font texture
		glGenTextures(1, &fontTex);
		glBindTexture(GL_TEXTURE_2D, fontTex);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

		unsigned char* pixels;
		int width, height;
		io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
		io.Fonts->TexID = &fontTex;

		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

		// Cleanup (don't clear the input data if you want to append new fonts later)
		io.Fonts->ClearInputData();
		io.Fonts->ClearTexData();
#else
		UNUSED(en);
#endif //AGE_ENABLE_IMGUI
		return true;
	}