void BFCLinkTracker::reset() { SCOPE_profile_cpu_function("BFC"); { SCOPE_profile_cpu_i("BFC", "ResetLinks"); for (auto &e : _links) { // beurk if (e != nullptr) { e->resetBFCTrackerIndex(); for (auto &cullable : e->_cullables) { auto &item = e->_bfcBlockFactory->getItem(cullable.getItemId()); item.setPosition(cullable.getPtr()->setBFCTransform(e->_globalTransformation)); } e = nullptr; } } _links.clear(); } { SCOPE_profile_cpu_i("BFC", "ResetFree"); //beurk while (!_free.empty()) _free.pop(); } }
bool RenderThread::update() { /* - Tant qu'il n'y a pas de command -> je pop des task - Une fois que j'ai mes commandes -> pour chacunes d'elles -> je regarde si c'est a moi de les traiter (ex : changement de scene) -> si ca n'est pas a moi de les traiter -> je les passe au render context actif -> si il n'y a pas de render context actif, c'est que j'ai fait une erreur, et j'assert dans ta face :D */ _registerId(); _run = true; _insideRun = true; DWORD threadId = GetThreadId(static_cast<HANDLE>(_threadHandle.native_handle())); SetThreadName(threadId, this->_name.c_str()); TMQ::MessageBase *task = nullptr; while (_run && _insideRun) { SCOPE_profile_cpu_i("RenderTimer", "Update"); if (TMQ::TaskManager::RenderThreadGetTask(task)) { SCOPE_profile_cpu_i("RenderTimer", "Execute task"); auto success = execute(task); // we receive a task that we cannot treat AGE_ASSERT(success); } } return true; }
bool MainThread::update() { SCOPE_profile_cpu_function("Main thread"); std::chrono::system_clock::time_point waitStart; std::chrono::system_clock::time_point waitEnd; std::chrono::system_clock::time_point workStart; std::chrono::system_clock::time_point workEnd; std::size_t workCount = 0; std::size_t waitCount = 0; workStart = std::chrono::high_resolution_clock::now(); if (_frameCounter - GetRenderThread()->getCurrentFrameCount() > 2) { _isRenderFrame = false; } else { _isRenderFrame = true; } if (!_engine->update()) { return false; } { SCOPE_profile_cpu_i("MainThread", "Execute tasks"); { TMQ::MessageBase *task = nullptr; while (TMQ::TaskManager::MainThreadGetTask(task)) { SCOPE_profile_cpu_i("MainThread", "Execute task"); auto result = execute(task); assert(result); // we receive a task that we cannot handle } } } workEnd = std::chrono::high_resolution_clock::now(); workCount = std::chrono::duration_cast<std::chrono::microseconds>(workEnd - workStart).count(); workCount -= waitCount; if (_isRenderFrame) { ++_frameCounter; } return true; }
bool MainThread::tryToStealTasks() { SCOPE_profile_cpu_i("MainThread", "Steal tasks"); { TMQ::MessageBase *task = nullptr; if (TMQ::TaskManager::MainThreadGetTask(task)) { SCOPE_profile_cpu_i("MainThread", "Execute task"); auto result = execute(task); assert(result); // we receive a task that we cannot handle return true; } } return false; }
void DepthOfField::renderPass(const DRBCameraDrawableList &infos) { if (infos.cameraInfos.data.dof) { SCOPE_profile_gpu_i("Depth of field"); SCOPE_profile_cpu_i("RenderTimer", "Depth of field"); _depth->bind(); _depth->generateMipmaps(); OpenGLState::glDepthMask(GL_FALSE); OpenGLState::glDisable(GL_DEPTH_TEST); OpenGLState::glDisable(GL_STENCIL_TEST); OpenGLState::glDisable(GL_CULL_FACE); _programs[PROGRAM_DEPTH_OF_FIELD]->use(); _programs[PROGRAM_DEPTH_OF_FIELD]->get_resource<Sampler2D>(StringID("cleanMap", 0x90c5a5421e083038)).set(_clean); _programs[PROGRAM_DEPTH_OF_FIELD]->get_resource<Sampler2D>(StringID("depthMap", 0xeb35b90435165cd4)).set(_depth); _programs[PROGRAM_DEPTH_OF_FIELD]->get_resource<Sampler2D>(StringID("blurredMap1", 0x031e7d3c1b84e96a)).set(_blurred1); _programs[PROGRAM_DEPTH_OF_FIELD]->get_resource<Sampler2D>(StringID("blurredMap2", 0x031e7c3c1b84e7b7)).set(_blurred2); _quadPainter->uniqueDrawBegin(_programs[PROGRAM_DEPTH_OF_FIELD]); _quadPainter->uniqueDraw(GL_TRIANGLES, _programs[PROGRAM_DEPTH_OF_FIELD], _quadVertices); _quadPainter->uniqueDrawEnd(); } }
void SdlContext::swapContext() { MicroProfileFlip(); { SCOPE_profile_cpu_i("RenderTimer", "swapContext"); SCOPE_profile_gpu_i("SwapContext"); SDL_GL_SwapWindow(_window); } }
IRenderingPipeline & ARenderingPipeline::render(const DRBCameraDrawableList &infos) { SCOPE_profile_cpu_i("RenderTimer", "RenderPipeline"); renderBegin(infos); // We iterate over the entry points5 for (auto &renderPass : _rendering_list) { renderPass->render(infos); } renderEnd(infos); return (*this); }
bool RenderThread::init() { registerCallback<Tasks::Render::CreateRenderContext>([this](Tasks::Render::CreateRenderContext &msg) { _context = msg.engine->setInstance<SdlContext, IRenderContext>(); auto configurationManager = msg.engine->getInstance<ConfigurationManager>(); auto w = configurationManager->getConfiguration<int>("windowW")->getValue(); auto h = configurationManager->getConfiguration<int>("windowH")->getValue(); auto f = configurationManager->getConfiguration<bool>("fullScreen")->getValue(); if (!_context->init(w, h, f, "~AGE~ V0.00001 Demo")) { msg.setValue(false); return; } if (_depthMapManager == nullptr) { _depthMapManager = new DepthMapManager; } #ifdef DEBUG _depthMapManager->init(1280, 720, 4); #else _depthMapManager->init(1280, 720, 2); #endif msg.setValue(true); }); registerCallback<Tasks::Render::InitRenderPipelines>([this](Tasks::Render::InitRenderPipelines &msg) { _context = msg.engine->setInstance<SdlContext, IRenderContext>(); pipelines.resize(RenderType::TOTAL); pipelines[DEFERRED] = std::make_unique<DeferredShading>(_context->getScreenSize(), paintingManager); pipelines[DEBUG_DEFERRED] = std::make_unique<DebugDeferredShading>(_context->getScreenSize(), paintingManager); _recompileShaders(); _initPipelines(); _bonesTexture = createRenderPassOutput<TextureBuffer>(8184 * 2, GL_RGBA32F, sizeof(glm::mat4), GL_DYNAMIC_DRAW); msg.setValue(true); }); registerCallback<Commands::ToRender::Flush>([&](Commands::ToRender::Flush& msg) { SCOPE_profile_cpu_i("RenderTimer", "Render frame"); if (msg.isRenderFrame) { #ifdef AGE_ENABLE_IMGUI std::shared_ptr<AGE::RenderImgui> imguiRenderList = nullptr; { std::lock_guard<AGE::SpinLock> lock(_mutex); imguiRenderList = _imguiRenderlist; } if (imguiRenderList != nullptr) { AGE::Imgui::getInstance()->renderThreadRenderFn(imguiRenderList->cmd_lists); } static bool first = true; if (first || imguiRenderList) { TMQ::TaskManager::emplaceMainTask<ImGuiEndOfFrame>(); first = false; } #endif _context->swapContext(); { SCOPE_profile_gpu_i("Clear buffer"); SCOPE_profile_cpu_i("RenderTimer", "Clear buffer"); glClear(GL_COLOR_BUFFER_BIT); } ++_frameCounter; if (_context) { _context->refreshInputs(); } } }); registerCallback<Tasks::Render::ReloadShaders>([&](Tasks::Render::ReloadShaders& msg) { #ifdef AGE_DEBUG _recompileShaders(); #else std::cerr << "Error : You cannot recompile shader at runtime. This feature is enabled only in debug mode\n"; #endif }); registerSharedCallback<AGE::Tasks::Basic::BoolFunction>([&](AGE::Tasks::Basic::BoolFunction& msg) { SCOPE_profile_cpu_i("RenderTimer", "Bool function"); msg.setValue(msg.function()); }); registerCallback<AGE::Tasks::Basic::VoidFunction>([&](AGE::Tasks::Basic::VoidFunction& msg) { SCOPE_profile_cpu_i("RenderTimer", "Void function"); if (msg.function) msg.function(); }); registerCallback<AGE::Tasks::Basic::Exit>([&](AGE::Tasks::Basic::Exit& msg) { AGE::GetEngine()->deleteInstance<IRenderContext>(); this->_insideRun = false; TMQ::TaskManager::emplaceSharedTask<Tasks::Basic::Exit>(); }); registerCallback<AGE::Tasks::Render::ContextGrabMouse>([&](AGE::Tasks::Render::ContextGrabMouse &msg) { _context->grabMouse(msg.grabMouse == 1 ? true : false); }); registerCallback<AGE::DRBCameraDrawableListCommand>([&](AGE::DRBCameraDrawableListCommand &msg) { std::shared_ptr<Painter> line2DPainter = nullptr; std::shared_ptr<Painter> line3DPainter = nullptr; std::shared_ptr<Painter> line3DPainterDepth = nullptr; //if (pipelines[msg.list->cameraInfos.data.pipeline]->isDebug()) //{ DebugDrawManager* debugDrawManager = nullptr; if (GetEngine()->hasInstance<DebugDrawManager>()) { debugDrawManager = GetEngine()->getInstance<DebugDrawManager>(); } if (debugDrawManager) { debugDrawManager->renderBegin(paintingManager); } pipelines[msg.list->cameraInfos.data.pipeline]->render(*msg.list.get()); if (debugDrawManager) { debugDrawManager->renderEnd(); } }); registerCallback<AGE::Tasks::UploadBonesToGPU>([&](AGE::Tasks::UploadBonesToGPU& msg) { SCOPE_profile_cpu_i("!!!HACK!!!", "Upload bones matrix to GPU"); _bonesTexture->set(msg.bones->data(), msg.bones->size()); }); return true; }
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); } }
void DeferredShadowBuffering::renderPass(const DRBCameraDrawableList &infos) { //@PROUT SCOPE_profile_gpu_i("DeferredShadowBuffering render pass"); SCOPE_profile_cpu_i("RenderTimer", "DeferredShadowBuffering render pass"); OpenGLState::glEnable(GL_CULL_FACE); OpenGLState::glCullFace(GL_FRONT); OpenGLState::glDepthMask(GL_TRUE); OpenGLState::glDepthFunc(GL_LEQUAL); OpenGLState::glDisable(GL_BLEND); OpenGLState::glDisable(GL_STENCIL_TEST); OpenGLState::glEnable(GL_DEPTH_TEST); OpenGLState::glDepthMask(GL_TRUE); OpenGLState::glDepthFunc(GL_LESS); _programs[PROGRAM_BUFFERING]->use(); // handle the number of sample if (_depthBuffers.size() < infos.spotLights.size()) { std::size_t count = infos.spotLights.size() - _depthBuffers.size(); for (int index = 0; index < count; ++index) { _depthBuffers.push_back(createRenderPassOutput<Texture2D>(_frame_buffer.width(), _frame_buffer.height(), GL_DEPTH24_STENCIL8, true)); _depthBuffers.back()->bind(); _depthBuffers.back()->parameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST); _depthBuffers.back()->parameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST); _depthBuffers.back()->parameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); _depthBuffers.back()->parameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); _depthBuffers.back()->parameter(GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); } } else if (_depthBuffers.size() > infos.spotLights.size()) { std::size_t count = _depthBuffers.size() - infos.spotLights.size(); for (int index = 0; index < count; ++index) { _depthBuffers.pop_back(); } } // start to render to texture for each depth map auto it = _depthBuffers.begin(); std::shared_ptr<Painter> painter = nullptr; std::shared_ptr<Painter> oldPainter = nullptr; for (auto &spotLightPtr : infos.spotLights) { SCOPE_profile_gpu_i("Spotlight pass"); SCOPE_profile_cpu_i("RenderTimer", "Spotlight pass"); DRBSpotLightData *spotlight = (DRBSpotLightData*)(spotLightPtr->spotLight.get()); glViewport(0, 0, _frame_buffer.width(), _frame_buffer.height()); _frame_buffer.attachment(*(*it), GL_DEPTH_STENCIL_ATTACHMENT); glClear(GL_DEPTH_BUFFER_BIT); _programs[PROGRAM_BUFFERING]->registerProperties(spotlight->globalProperties); _programs[PROGRAM_BUFFERING]->updateProperties(spotlight->globalProperties); // draw for the spot light selected for (auto &meshPaint : spotLightPtr->meshs) { auto mesh = (DRBMeshData*)(meshPaint.get()); //temporary //todo, do not spawn entity while mesh is not loaded //currently it's not safe, because the paiter key can be invalid //during the first frames if (mesh->getPainterKey().isValid()) { painter = _painterManager->get_painter(mesh->getPainterKey()); if (painter != oldPainter) { if (oldPainter) { oldPainter->uniqueDrawEnd(); } painter->uniqueDrawBegin(_programs[PROGRAM_BUFFERING]); } oldPainter = painter; painter->uniqueDraw(GL_TRIANGLES, _programs[PROGRAM_BUFFERING], mesh->globalProperties, mesh->getVerticesKey()); } } spotlight->shadowMap = *it; ++it; } if (oldPainter) { oldPainter->uniqueDrawEnd(); } }
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; }