Direct 2D тормозит в полноэкранном режимеC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Direct 2D тормозит в полноэкранном режиме

Сообщение Anonymous »


Я использую Direct2D для игровой графики. В оконном режиме все нормально, но в полноэкранном режиме производительность иногда внезапно падает где-то на 80%. Такое случается даже если я использую 800x600. В приведенном примере он будет работать нормально в течение 1-2 минут, а затем отключится. Вы можете увидеть падение счетчика FPS, отображаемого в коде рендеринга. Я попробовал обновить графический драйвер. Я не вижу увеличения использования памяти с течением времени. Я публикую здесь основной код, и ссылка на урезанный полный пример проекта, который будет скомпилирован и/или включает в себя 2 исполняемые версии, в которых проблему можно увидеть (полноэкранный режим) и не увидеть (в оконном режиме).

Запуск программы

AdjustWindowRectEx(&windowRect, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, false, WS_EX_OVERLAPPEDWINDOW); mainWindow = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, wc.lpszClassName, L"Jet", WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, NULL, NULL, hInstance, NULL); HR =graphicsObject.init(mainWindow, fullScr, NULL); GraphicsObject.initWrite();//инициализируем DirectWrite GraphicsObject.bmpInit();//WICFactory и др. GraphicsObject.loadBrushes();//blackBrush и др. GraphicsObject.bmpLoad(L"Gfx\\MainSheet2.png", 200); GraphicsObject.getContext3()->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); destStride = sizeof(D2D1_RECT_U); HR =graphicsObject.spriteBatchInit(); init Direct 2D:

scd.BufferDesc.Width = 0; // ширина заднего буфера scd.BufferDesc.Height = 0; // высота scd.BufferDesc.RefreshRate.Numerator = 0; // частота обновления: 0 -> все равно scd.BufferDesc.RefreshRate.Denominator = 1; scd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; // используемая цветовая палитра scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; // неопределенный порядок строк сканирования scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; // неопределенное масштабирование scd.SampleDesc.Count = 1; // отключаем msaa scd.SampleDesc.Quality = 0; scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // используем задний буфер в качестве цели рендеринга scd.BufferCount = 3; // количество буферов в цепочке обмена (включая передний буфер) scd.OutputWindow = winHandle; // устанавливаем главное окно в качестве цели вывода //dxApp->appWindow->getMainWindowHandle(); scd.Windowed = !fullScreen; // оконный, / полноэкранный$ scd.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; // режим переворота и удаление буфера после представления scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; // разрешить переключение полноэкранного режима // не устанавливать, чтобы предотвратить createDeviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; Hres = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, 0, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &dev, &featureLevel, &devCon); d3dStarted = правда; _flushall(); Hres = dev.As(&dxgiDevice); Hres = dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()); Hres = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), &dxgiFactory); Hres = dxgiFactory->CreateSwapChain(dev.Get(), &scd, swapChain.GetAddressOf()); options.debugLevel = D2D1_DEBUG_LEVEL_NONE; Hres = (D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, __uuidof(ID2D1Factory3), &options, &factory)); Hres = Factory->CreateDevice(dxgiDevice.Get(), &dev2); Hres = dev2.As(&dev3); // выполняет QueryInterface Hres = dev3->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, &devCon3); d3dStarted = правда; Основной цикл

во время (bRunning) { if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } если (устройство потеряно) {MessageBox(NULL, L"УСТРОЙСТВО ПОТЕРЯНО *", L"Jet", MB_ICONEXCLAMATION | MB_OK);} еще { gameTick (основное окно); if (render(&graphicsObject, mainWindow, xRes, yRes, &mainMap) != S_OK) Бруннинг = ложь; фреймКаунт++; } } функция рендеринга

HRESULT render(gfx2d* gObj, HWND win, int xr, int yr, map* mapData) { ЧРЕЗУЛЬТАТ час; D2D1_RECT_F tmpRect_f; pVect vecToMouse; WCHAR debugStr[16]; int x = xScrolled / 32;//x индекс крайнего левого фрагмента экрана int y = yScrolled / 32;//y индекс самого верхнего фрагмента экрана плавать a, b, c, d; size_t cbDest = 16 * sizeof(WCHAR); LPCTSTR pszFormat; ID2D1SpriteBatch* пакетный указатель; gObj->getContext3()->BeginDraw(); gObj->getContext3()->Clear(D2D1::ColorF(0.0f, 0.0f, 0.1f, 1.0f)); buildSpriteBatch (gObj, MapData); BatchPointer = gObj->getSpriteBatchPointer(); gObj->getContext3()->DrawSpriteBatch(batchPointer, gObj->getBitmap(200), D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR, D2D1_SPRITE_OPTIONS_NONE); //отображение FPS: tmpRect_f = { 101,50, 200, 50 };//Слева, сверху, справа, снизу pszFormat = ТЕКСТ("%d"); час = StringCbPrintf (debugStr, cbDest, pszFormat, fps); gObj->getContext3()->DrawText(debugStr, wcslen(debugStr), gObj->getTxtFormat(1), &tmpRect_f, gObj->getBrush(1).Get()); hr = gObj->getContext3()->EndDraw(); hr = gObj->Present(); вернуть S_OK; } создать пакет спрайтов для рендеринга

void buildSpriteBatch(gfx2d* gObj2, map* theMap) { ЧРЕЗУЛЬТАТ час; беззнаковое число = 0; интервал плитки; int x = xScrolled / TILESIZE;//x индекс крайнего левого фрагмента экрана int y = yScrolled / TILESIZE;//y индекс самой верхней плитки экрана ПВХ слой, смола; ПРЯМОЙ р; D2D1_RECT_U sourceRects[8000]; //UINT32 слева, сверху, справа, снизу D2D1_RECT_F destRects[8000];// D2D1::RectF(Left.0f,top.0f,right.0f,bottom.0f); gObj2->ClearSpriteBatch(); //Добавляем вражеские спрайты mainEnemyList.init(); в то время как (!mainEnemyList.atEnd()) { if (mainEnemyList.getCurrent()->getX() * ​​TILESIZE >= xScrolled && mainEnemyList.getCurrent()->getX() * ​​TILESIZE < xScrolled+xRes && mainEnemyList.getCurrent()->getY() * TILESIZE >= yScrolled && mainEnemyList.getCurrent()->getY() * TILESIZE getAni(0)->getCurrent()->getSource(); sourceRects[count].left = r.left; sourceRects[count].top = r.top; sourceRects[count].right = r.right; sourceRects[count].bottom = r.bottom; destRects[count].left = (mainEnemyList.getCurrent()->getX() * ​​TILESIZE) - xScrolled; destRects[count].top = ((mainEnemyList.getCurrent()->getY() + 2) * TILESIZE) - yScrolled;//+2 для hud destRects[count].right = destRects[count].left + mainEnemyList.getCurrent()->getWidth() * TILESIZE; destRects[count].bottom = destRects[count].top + mainEnemyList.getCurrent()->getHeight() * TILESIZE; считать++; } mainEnemyList.advance(); } //Добавляем плитки while (x < (xScrolled / TILESIZE) + (xRes / TILESIZE) + 2 && x < theMap->getWidth()) { y = yПрокрутка/TILESIZE; while (y < (yScrolled / TILESIZE) + (yRes / TILESIZE) + 2 && y < theMap->getHeight()) { tileID = theMap->getID(x, y); if (tileID && tileID != 99)//id 0 = нет плитки для рисования. 99=пустое пространство. { если (theMap->isAnimated(x, y)) { if(theMap->isHazard(x, y)) tileID += lavaFrame; } //Установить источник только на основе идентификатора: sourceRects[count].top = mainMap.getSprHeightRef();//51/34 sourceRects[count].bottom = mainMap.getSprHeightRef() + 15;//66/49 sourceRects[count].left = (tileID - 1) * 17; sourceRects[count].right = sourceRects[count].left + 16; //добавляем прямоугольник назначения на основе xy+прокрутки //по мере увеличения yScroll мы рисуем «выше вверх» destRects[count].top = (float)((y + 2) * TILESIZE) - yScrolled;//+2 =рисовать в 2 раза ниже на экране для HUD destRects[count].bottom = (float)((y + 2) * TILESIZE + TILESIZE) - yScrolled;//+2 =рисовать в 2 раза ниже на экране для hud destRects[count].left = (float)((x * TILESIZE) - xScrolled); destRects[count].right = (float)((x * TILESIZE) + TILESIZE - xScrolled); считать++; } у++; } х++; } //Добавляем ноги игрока: sourceRects[count].top = 1; sourceRects[count].bottom = 15; sourceRects[count].left = 180; sourceRects[count].right = 196; destRects[count].top = ((playerY + 3) * TILESIZE) - yScrolled; destRects[count].bottom = destRects[count].top + TILESIZE; destRects[count].left = (playerX * TILESIZE) - xScrolled; destRects[count].right = destRects[count].left + TILESIZE; считать++; //Добавить тело: sourceRects[count].top = 1; sourceRects[count].bottom = sourceRects[count].top + 25;//52 sourceRects[count].left = 36; курфраме = 9; sourceRects[count].right = sourceRects[count].left + 18;//кажется, нам нужно +1, чтобы включить самый правый пиксель destRects[count].top = ((playerY+2) * TILESIZE) - yScrolled; destRects[count].bottom = destRects[count].top + 50; destRects[count].left = (playerX * TILESIZE) - xScrolled; destRects[count].right = destRects[count].left+ TILESIZE; считать++; hr = gObj2->getSpriteBatch()->AddSprites(count, destRects, sourceRects, NULL, NULL, destStride, destStride, 0, 0); } Ссылка на проект для скачивания https://drive.google.com/file/d/1RPdr6v ... sp=sharing для компиляции вам может потребоваться добавить зависимости: ;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;% (Дополнительные зависимости)
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»