SDLSurfacePtr GLVideoSystem::make_screenshot() { GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); const int& viewport_x = viewport[0]; const int& viewport_y = viewport[1]; const int& viewport_width = viewport[2]; const int& viewport_height = viewport[3]; SDLSurfacePtr surface = SDLSurface::create_rgb(viewport_width, viewport_height); std::vector<char> pixels(3 * viewport_width * viewport_height); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(viewport_x, viewport_y, viewport_width, viewport_height, GL_RGB, GL_UNSIGNED_BYTE, pixels.data()); SDL_LockSurface(surface.get()); for (int i = 0; i < viewport_height; i++) { char* src = &pixels[3 * viewport_width * (viewport_height - i - 1)]; char* dst = (static_cast<char*>(surface->pixels)) + i * surface->pitch; memcpy(dst, src, 3 * viewport_width); } SDL_UnlockSurface(surface.get()); return surface; }
CTexture2DSharedPtr LoadFromDisk(const path &path)const { SDLSurfacePtr pSurface = LoadFileImage(path); const bool hasAlpha = SDL_ISPIXELFORMAT_ALPHA(pSurface->format->format); // Все изображения будем конвертировать в RGB или RGBA, // в зависимости от наличия альфа-канала в исходном изображении. const uint32_t requiredFormat = hasAlpha ? SDL_PIXELFORMAT_ABGR8888 : SDL_PIXELFORMAT_RGB24; if (pSurface->format->format != requiredFormat) { pSurface.reset(SDL_ConvertSurfaceFormat(pSurface.get(), requiredFormat, 0)); } // В системе координат OpenGL отсчёт идёт с нижней левой точки, // а не с верхней левой, поэтому переворачиваем изображение. CUtils::FlipSurfaceVertically(*pSurface); auto pTexture = std::make_shared<CTexture2D>(); pTexture->Bind(); pTexture->ApplyImageData(*pSurface); pTexture->ApplyTrilinearFilter(); pTexture->ApplyMaxAnisotropy(); pTexture->ApplyWrapMode(m_wrapS, m_wrapT); pTexture->GenerateMipmaps(); pTexture->Unbind(); return pTexture; }