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); }
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); } }
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; }