Esempio n. 1
0
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;
    }