Example #1
1
BEE::RGBA BEE::get_pixel_color(int x, int y) {
	SDL_Surface *screenshot = SDL_CreateRGBSurface(0, width, height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
	SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ARGB8888, screenshot->pixels, screenshot->pitch);

	RGBA color;
	SDL_GetRGBA(((Uint32*)screenshot->pixels)[x+y*height], screenshot->format, &color.r, &color.g, &color.b, &color.a);

	SDL_FreeSurface(screenshot);

	return color;
}
Example #2
0
/**
 * @brief Takes a screenshot of the current rendered screen and then saves it to a .bmp
 */
void GameWindow::screenshot()
{
	//Skip the screenshot if the Game Window is not inited
	if( this->inited == false )
	{
		return;
	}

	SDL_Rect clip;
	clip.x = 0;
	clip.y = 0;

	//Get the size of the screen to be taken
	SDL_GetWindowSize( this->window , &clip.w , &clip.h );

	//Get the window surface
	SDL_Surface* surface = SDL_GetWindowSurface( this->window );

	//Make sire you have the surface
	if ( surface == NULL )
	{
		std::cout << "SDL Render Error : " << SDL_GetError() << std::endl;
		return;
	}

	//Copy the pixels in the renderer to the surface's pixels
	SDL_RenderReadPixels( this->renderer , &clip , SDL_GetWindowPixelFormat( this->window ) , surface->pixels , surface->pitch );

	//Save the bitmap
	//TODO: Improve Naming Scheme
	std::stringstream ss;
#ifdef STD_PUT_TIME
	std::time_t t = std::time( nullptr );
	std::tm tm = *std::localtime( &t );
	ss << "akora-" << std::put_time( &tm, "%Y-%m-%d %H-%M-%S" ) << ".bmp";
#else
	time_t rawtime;
	struct tm* timeinfo;
	char buffer [80];

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	strftime ( buffer, 80, "%Y-%m-%d %H-%M-%S", timeinfo );

	ss << "akora-" << etc::trim( std::string( buffer ) ) << ".bmp";
#endif
	SDL_SaveBMP( surface , ss.str().c_str() );
	//Tidy up surface
	SDL_FreeSurface( surface );


}
Example #3
0
File: draw.c Project: nnesse/tbftss
void saveScreenshot(void)
{
    static int i = 0;
    char filename[MAX_NAME_LENGTH];
    SDL_Surface *sshot;

    sprintf(filename, "/tmp/tbftss/%d.bmp", ++i);

    sshot = SDL_CreateRGBSurface(0, SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
    SDL_RenderReadPixels(app.renderer, NULL, SDL_PIXELFORMAT_ARGB8888, sshot->pixels, sshot->pitch);
    SDL_SaveBMP(sshot, filename);
    SDL_FreeSurface(sshot);
}
Example #4
0
void gfxTakeScreenshot() {
    std::stringstream fileStream;
    fileStream << "gameyob_" << time(NULL) << ".bmp";

    int w;
    int h;
    SDL_GetWindowSize(window, &w, &h);

    SDL_Surface *surface = SDL_CreateRGBSurface(0, w, h, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
    SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ARGB8888, surface->pixels, surface->pitch);
    SDL_SaveBMP(surface, fileStream.str().c_str());
    SDL_FreeSurface(surface);
}
Example #5
0
SDL_Texture *renderer::screenshot(SDL_Window* w){
    SDL_Texture* img = nullptr;

    SDL_Surface* surface = SDL_GetWindowSurface(w);
    SDL_Renderer* renderer = SDL_GetRenderer(w);
    if(surface && renderer){
        SDL_RenderReadPixels(renderer,&surface->clip_rect,surface->format->format
                             ,surface->pixels,surface->pitch);
        img = SDL_CreateTextureFromSurface(renderer,surface);
    }

    return img;
}
Example #6
0
void Render_SW_SDL::getScreenPixels(int x, int y, int w, int h, unsigned char *pixels)
{
    SDL_Rect rect;
    rect.x = x;
    rect.y = y;
    rect.w = w;
    rect.h = h;
    SDL_RenderReadPixels( m_gRenderer,
                          &rect,
                          SDL_PIXELFORMAT_BGR24,
                          pixels,
                          w*3 + (w%4) );
}
Example #7
0
void chip8emu::Chip8Emu::takeSnapshot()
{
   // Generate the snapshot filename ...
   std::string filename = generateFilename("snap_", ".bmp");

   // ... and store the current screen as bitmap.
   std::shared_ptr<SDL_Surface> sshot = std::shared_ptr<SDL_Surface>(SDL_GetWindowSurface(mWindow.get()), SDL_FreeSurface);
   Uint32 format = SDL_GetWindowPixelFormat(mWindow.get());
   SDL_RenderReadPixels(mRenderer.get(), nullptr, format, sshot->pixels, sshot->pitch);
   SDL_SaveBMP(sshot.get(), filename.c_str());
   
   std::cout << "Saved snapshot as " << filename << " ..." << std::endl;
}
Example #8
0
Texture* Renderer::screenshot()
{
    SDL_Surface* window = SDL_GetWindowSurface(sdlWindow());
    if (!window)
    {
        throw Exception(SDL_GetError());
    }

    auto texture = new Texture(window->w, window->h);
    auto surface = texture->sdlSurface();
    SDL_RenderReadPixels(_sdlRenderer, NULL, surface->format->format, surface->pixels, surface->pitch);
    SDL_FreeSurface(window);
    return texture;
}
Example #9
0
//recup des pixels de la fenĂȘtre sur w largeur et h longueur
int SDLS_getpixels(Uint32* pixels, int w, int h)
{
    int res;
    int width=w;//, height=h;
    //SDL_RenderGetLogicalSize(ren,&width,&height);
    //printf("%d %d\n",width,height);
    res = SDL_RenderReadPixels(gRenderer,NULL,SDL_PIXELFORMAT_ARGB8888,pixels,width*sizeof(Uint32));
    if (res<0)
    {
        fprintf(stderr,"Erreur getpixels : %s\n",SDL_GetError());
        return -1;
    }
    return 0;
}
Example #10
0
static rfbBool resize(rfbClient* client) {
  int width=client->width,height=client->height,
    depth=client->format.bitsPerPixel;

  client->updateRect.x = client->updateRect.y = 0;
  client->updateRect.w = width; client->updateRect.h = height;

  sdlWindow = SDL_CreateWindow("DRC VNC Viewer",//client->desktopName,
                               SDL_WINDOWPOS_UNDEFINED,
                               SDL_WINDOWPOS_UNDEFINED,
                               width, height,
                               SDL_WINDOW_OPENGL);
  sdlRenderer = SDL_CreateRenderer(sdlWindow, -1,
                                   SDL_RENDERER_ACCELERATED);
//                                 SDL_RENDERER_SOFTWARE);

  sdlTexture = SDL_CreateTexture(sdlRenderer,
                                 SDL_PIXELFORMAT_ARGB8888,
                                 SDL_TEXTUREACCESS_STREAMING,
                                 width, height);

  SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);

  // blank the window
  SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
  SDL_RenderClear(sdlRenderer);

  SDL_RenderPresent(sdlRenderer);

  SDL_PixelFormat *fmt = SDL_AllocFormat(SDL_PIXELFORMAT_ARGB8888);

  uint8_t *pixels = static_cast<uint8_t*>
                      (malloc(drc::kScreenWidth * drc::kScreenHeight *
                      fmt->BytesPerPixel));
  SDL_RenderReadPixels(sdlRenderer, NULL, SDL_PIXELFORMAT_ARGB8888, pixels,
    drc::kScreenWidth * fmt->BytesPerPixel);
  client->frameBuffer=pixels;

  client->format.bitsPerPixel = fmt->BitsPerPixel;
  client->format.redShift     = fmt->Rshift;
  client->format.greenShift   = fmt->Gshift;
  client->format.blueShift    = fmt->Bshift;
  client->format.redMax       = fmt->Rmask>>client->format.redShift;
  client->format.greenMax     = fmt->Gmask>>client->format.greenShift;
  client->format.blueMax      = fmt->Bmask>>client->format.blueShift;
  SetFormatAndEncodings(client);

  return TRUE;
}
Example #11
0
void* SDLRenderer::takeScreenshot() {
    int width, height;
    SDL_QueryTexture(offscreenTexture, nullptr, nullptr, &width, &height);

    char* pixels = new char[3 * width * height];

    if (SDL_RenderReadPixels(renderer, nullptr, SDL_PIXELFORMAT_RGB24, pixels, 3 * width) != 0) {
        delete[] pixels;
        return nullptr;
    }

    SDL_Surface* sdlSurface = SDL_CreateRGBSurfaceFrom(
        pixels, width, height, 24, 3 * width, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000);
    return sdlSurface;
}
Example #12
0
void Image::Save(const char* aFile)
{
	SDL_Surface* SaveSurface = SDL_CreateRGBSurface(0, mWidth, mHeight, 32, 0xFF000000, 0xFF0000, 0xFF00, 0xFF);
	if (!SaveSurface)
	{
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Failed to save image", SDL_GetError(), NULL);
		return;
	}
	if (SDL_RenderReadPixels(mRenderer, NULL, SaveSurface->format->format, SaveSurface->pixels, SaveSurface->pitch) < 0)
	{
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Failed to save image", SDL_GetError(), NULL);
		return;
	}
	if (SDL_SaveBMP(SaveSurface, aFile) < 0)
	{
		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Failed to save image", SDL_GetError(), NULL);
		return;
	}
	SDL_FreeSurface(SaveSurface);
}
Example #13
0
void saveToBitmap(char *filename, SDL_Window *win, SDL_Renderer *rend)
{
	SDL_Surface *temp = SDL_CreateRGBSurface(0,SCREEN_WIDTH, SCREEN_HEIGHT, 32, 0, 0, 0, 0);
	SDL_RenderReadPixels(rend, NULL, SDL_PIXELFORMAT_ARGB8888, temp->pixels, temp->pitch);
	if(!temp)
	{
		fprintf(stderr, "NON FATAL ERROR : SDL_RenderReadPixels() has failed  : %s\n", SDL_GetError());
		return;
	
	}
	if(SDL_SaveBMP(temp, filename) != 0)
	{
	
		fprintf(stderr, "NON FATAL ERROR : SDL_SaveBMP() has failed  : %s\n", SDL_GetError());
	
	}
	SDL_FreeSurface(temp);



}
Example #14
0
int BEE::save_screenshot(std::string filename) { // Slow, use sparingly
	if (options->is_opengl) {
		unsigned char* pixels = new unsigned char[width*height*4]; // 4 bytes for RGBA
		glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

		SDL_Surface* screenshot  = SDL_CreateRGBSurfaceFrom(pixels, width, height, 8*4, width*4, 0,0,0,0);
		SDL_SaveBMP(screenshot, filename.c_str());

		SDL_FreeSurface(screenshot);
		delete [] pixels;
	} else {
		SDL_Surface *screenshot = SDL_CreateRGBSurface(0, width, height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
		SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ARGB8888, screenshot->pixels, screenshot->pitch);

		SDL_SaveBMP(screenshot, filename.c_str());

		SDL_FreeSurface(screenshot);
	}

	return 0;
}
Example #15
0
void SDLFrontend::makeScreenshot (const std::string& filename)
{
	assert(_renderer);

	SDL_Rect viewport;
	int bpp;
	Uint32 rmask, gmask, bmask, amask;

	SDL_RenderGetViewport(_renderer, &viewport);

	SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGBA8888, &bpp, &rmask, &gmask, &bmask, &amask);
	ScopedPtr<SDL_Surface> surface(SDL_CreateRGBSurface(0, viewport.w, viewport.h, bpp, rmask, gmask, bmask, amask));
	if (!surface)
		return;

	if (SDL_RenderReadPixels(_renderer, nullptr, surface->format->format, surface->pixels, surface->pitch) < 0)
		return;

	const std::string fullFilename = FS.getAbsoluteWritePath() + filename + "-" + dateutil::getDateString() + ".png";
	IMG_SavePNG(surface, fullFilename.c_str());
}
Example #16
0
void SaveScreenshot()
{
        char Filename[52];
        SDL_Rect viewport;
        SDL_Surface* surface;

        Screenshot::GenerateName( Filename );
        if( Filename[0] == '\0' ){
                stat("Can not get screenshot name. Too many screenshots in folder");
                return;
        }
        SDL_RenderGetViewport(renderer, &viewport);
        surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24,
        #if SDL_BYTEORDER == SDL_BIG_ENDIAN
            0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff
        #else
            0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000
        #endif
        );

        if (!surface)
        {
            stat("Couldn't create surface: %s\n", SDL_GetError());
            return;
        }

        if ( SDL_RenderReadPixels(renderer, NULL, surface->format->format, surface->pixels, surface->pitch) < 0 )
        {
            stat("Couldn't read screen: %s\n", SDL_GetError());
            return;
        }

        if( png_save_surface(Filename, surface) < 0 ){
                SDL_FreeSurface( surface );
                return;
        }
        SDL_FreeSurface( surface );
        return;

}
Example #17
0
    void to_file::render(SDL_Renderer* renderer)
    {
        if (m_screenshot == NULL)
        {
            int32_t width;
            int32_t height;

            SDL_GetRendererOutputSize(renderer, &width, &height);

            m_screenshot = SDL_CreateRGBSurface(0, width, height, 32,
                0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
        }

        SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ARGB8888,
            m_screenshot->pixels, m_screenshot->pitch);

        std::stringstream file;
        file << m_directory
             << std::setw(9) << std::setfill('0') << m_files << ".bmp";
        SDL_SaveBMP(m_screenshot, file.str().c_str());
        m_files++;
    }
Example #18
0
SDL_Surface *Renderer::getScreenshot() const
{
    const Int2 dimensions = this->getWindowDimensions();
    SDL_Surface *screenshot = Surface::createSurfaceWithFormat(
                                  dimensions.getX(), dimensions.getY(),
                                  Renderer::DEFAULT_BPP, Renderer::DEFAULT_PIXELFORMAT);

    int status = SDL_RenderReadPixels(this->renderer, nullptr,
                                      screenshot->format->format, screenshot->pixels, screenshot->pitch);

    if (status == 0)
    {
        Debug::mention("Renderer", "Screenshot taken.");
    }
    else
    {
        Debug::crash("Renderer", "Couldn't take screenshot, " +
                     std::string(SDL_GetError()));
    }

    return screenshot;
}
Example #19
0
static void
SDLTest_ScreenShot(SDL_Renderer *renderer)
{
    SDL_Rect viewport;
    SDL_Surface *surface;

    if (!renderer) {
        return;
    }

    SDL_RenderGetViewport(renderer, &viewport);
    surface = SDL_CreateRGBSurface(0, viewport.w, viewport.h, 24,
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
                    0x00FF0000, 0x0000FF00, 0x000000FF,
#else
                    0x000000FF, 0x0000FF00, 0x00FF0000,
#endif
                    0x00000000);
    if (!surface) {
        fprintf(stderr, "Couldn't create surface: %s\n", SDL_GetError());
        return;
    }

    if (SDL_RenderReadPixels(renderer, NULL, surface->format->format,
                             surface->pixels, surface->pitch) < 0) {
        fprintf(stderr, "Couldn't read screen: %s\n", SDL_GetError());
        SDL_free(surface);
        return;
    }

    if (SDL_SaveBMP(surface, "screenshot.bmp") < 0) {
        fprintf(stderr, "Couldn't save screenshot.bmp: %s\n", SDL_GetError());
        SDL_free(surface);
        return;
    }
}
Example #20
0
int video_area_capture(surface *sur, int x, int y, int w, int h) {
    float scale_x = (float)state.w / NATIVE_W;
    float scale_y = (float)state.h / NATIVE_H;

    // Correct position (take scaling into account)
    SDL_Rect r;
    r.x = x * scale_x;
    r.y = y * scale_y;
    r.w = w * scale_x;
    r.h = h * scale_y;

    // Create a new surface
    surface_create(sur, SURFACE_TYPE_RGBA, r.w, r.h);

    // Read pixels
    int ret = SDL_RenderReadPixels(state.renderer, &r, SDL_PIXELFORMAT_ABGR8888, sur->data, sur->w * 4);
    if(ret != 0) {
        surface_free(sur);
        PERROR("Unable to read pixels from renderer: %s", SDL_GetError());
        return 1;
    }

    return 0;
}
Example #21
0
static int sdl_display_read(const struct device *dev, const u16_t x,
			    const u16_t y,
			    const struct display_buffer_descriptor *desc,
			    void *buf)
{
	struct sdl_display_data *disp_data =
		(struct sdl_display_data *)dev->driver_data;
	SDL_Rect rect;

	rect.x = x;
	rect.y = y;
	rect.w = desc->width;
	rect.h = desc->height;

	LOG_DBG("Reading %dx%d (w,h) bitmap @ %dx%d (x,y)", desc->width,
			desc->height, x, y);

	__ASSERT(desc->width <= desc->pitch, "Pitch is smaller then width");
	__ASSERT((3 * desc->pitch * desc->height) <= desc->buf_size,
			"Input buffer to small");

	return SDL_RenderReadPixels(disp_data->renderer, &rect, 0, buf,
			4 * desc->pitch);
}
Example #22
0
/**
* \fn void screenshot()
* \brief Make a screenshot of the screen
*
* \return void
*/
void screenshot()
{
	int w, h;
	int i = 0;
	const char* mainPath = "../assets/screenshot/";
	char path[50];
	char screenshotName[29];
	time_t t1;
	t1 = time(NULL);
	SDL_Surface* surfaceScreenshot = NULL;
	SDL_GetRendererOutputSize(globalRenderer, &w, &h);
	surfaceScreenshot = SDL_CreateRGBSurface(0, w, h, 32, RMASK, GMASK, BMASK, AMASK);
	SDL_RenderReadPixels(globalRenderer, NULL, SDL_PIXELFORMAT_ABGR8888, surfaceScreenshot->pixels, surfaceScreenshot->pitch);
	strcpy(path, mainPath);
	sprintf(screenshotName, "%s\0", ctime(&t1));
	strcat(path, screenshotName);
	memcpy(path + strlen(mainPath) + 3, "_", 1);
	memcpy(path + strlen(mainPath) + 7, "_", 1);
	for (i = 10; i < 22; i += 3)
		memcpy(path + strlen(mainPath) + i, ".", 1);
	memcpy(path + strlen(mainPath) + strlen(screenshotName) - 1, ".bmp\0", 5);
	SDL_SaveBMP(surfaceScreenshot, path);
	SDL_FreeSurface(surfaceScreenshot);
}
Example #23
0
bool
SDLRenderer::pixels(Uint8 pixels[], int pitch) {
    return SDL_RenderReadPixels(_renderer, nullptr, SDL_PIXELFORMAT_RGB24, pixels, pitch) == 0;
}
Example #24
0
void Viewer::mainloop() {
    Timer timer;
    Timer total;

    if (m_print_perf)
        fmt::print("Rendering frame {}\n", m_frame);
    m_scene_changed = false;
    m_frame++;

    int current_time = SDL_GetTicks();
    double dt = (current_time - m_last_frame_time) / 1000.0;
    m_last_frame_time = current_time;
    auto fps = 1. / dt;

    // Input
    SDL_Event e;
    while (SDL_PollEvent(&e)) {
        if (e.type == SDL_QUIT) {
            shutdown();
        }

        if (e.type == SDL_KEYDOWN) {
            if (e.key.keysym.sym == SDLK_ESCAPE) {
                shutdown();
            }
            if (e.key.keysym.sym == SDLK_b) {
                m_debug = !m_debug;
            }
            if (e.key.keysym.sym == SDLK_n) {
                m_print_perf = !m_print_perf;
            }
            if (e.key.keysym.sym == SDLK_1) {
                m_stride_x = 1;
                m_stride_y = 1;
                m_scene_changed = true;
            }
            if (e.key.keysym.sym == SDLK_2) {
                m_stride_x = 2;
                m_stride_y = 2;
                m_scene_changed = true;
            }
            if (e.key.keysym.sym == SDLK_3) {
                m_stride_x = 4;
                m_stride_y = 4;
                m_scene_changed = true;
            }
        }

        if (e.type == SDL_MOUSEBUTTONDOWN) {
            if (e.button.button == SDL_BUTTON_RIGHT) {
                if (m_look_mode) {
                    m_look_mode = false;
                    SDL_SetRelativeMouseMode(SDL_FALSE);
                } else if (!m_look_mode) {
                    m_look_mode = true;
                    SDL_SetRelativeMouseMode(SDL_TRUE);
                }
            }
        }
    }

    float cam_speed = .8f * dt;

    // Left/right
    const uint8_t *keystates = SDL_GetKeyboardState(0);
    if (keystates[SDL_SCANCODE_A]) {
        m_scene_changed = true;
        Camera::set_pos(m_camera, Camera::pos(m_camera) - Camera::right(m_camera) * cam_speed);
    } else if (keystates[SDL_SCANCODE_D]) {
        Camera::set_pos(m_camera, Camera::pos(m_camera) + Camera::right(m_camera) * cam_speed);
        m_scene_changed = true;
    }

    // Up/down
    if (keystates[SDL_SCANCODE_SPACE]) {
        m_scene_changed = true;
        Camera::set_pos(m_camera, Camera::pos(m_camera) + glm::vec3{0, 1, 0} * cam_speed);
    } else if (keystates[SDL_SCANCODE_LCTRL]) {
        m_scene_changed = true;
        Camera::set_pos(m_camera, Camera::pos(m_camera) - glm::vec3{0, 1, 0} * cam_speed);
    }

    // Roll
    if (keystates[SDL_SCANCODE_Q]) {
        m_scene_changed = true;
        Camera::set_world_up(m_camera, glm::rotateZ(Camera::up(m_camera), 0.1f));
    } else if (keystates[SDL_SCANCODE_E]) {
        m_scene_changed = true;
        Camera::set_world_up(m_camera, glm::rotateZ(Camera::up(m_camera), -0.1f));
    }

    // Front/back
    if (keystates[SDL_SCANCODE_W]) {
        m_scene_changed = true;
        Camera::set_pos(m_camera, Camera::pos(m_camera) + Camera::dir(m_camera) * cam_speed);
    } else if (keystates[SDL_SCANCODE_S]) {
        m_scene_changed = true;
        Camera::set_pos(m_camera, Camera::pos(m_camera) - Camera::dir(m_camera) * cam_speed);
    }

    // Rendering here
    int width;
    int height;
    SDL_GetWindowSize(m_window, &width, &height);

    glm::ivec2 mouse_pos;
    if (m_look_mode) {
        // Yaw
        SDL_GetRelativeMouseState(&(mouse_pos.x), &(mouse_pos.y));
        if (mouse_pos.x != 0) {
            m_scene_changed = true;
            Camera::set_dir(m_camera, glm::rotateY(Camera::dir(m_camera), mouse_pos.x * 0.001f));
        }

        // Pitch
        if (mouse_pos.y != 0) {
            m_scene_changed = true;
            Camera::set_dir(m_camera,
                            glm::rotate(Camera::dir(m_camera), mouse_pos.y * 0.001f,
                                        glm::cross(Camera::up(m_camera), Camera::dir(m_camera))));
        }

    } else if (!m_look_mode) {
        SDL_GetMouseState(&(mouse_pos.x), &(mouse_pos.y));
    }

    if (m_scene_changed) {
        m_samples_accumulated = 0;
    }

    if (m_print_perf)
        fmt::print("    {:<15} {:>10.3f} ms\n", "Input handling", timer.elapsed());

    Scene::rebuild(m_scene);

    if (m_print_perf)
        fmt::print("    {:<15} {:=10.3f} ms\n", "Scene rebuild", timer.elapsed());

    const auto luminance = m_renderer->render(m_scene_changed, m_stride_x, m_stride_y);
    if (m_print_perf) {
        m_renderer->print_last_frame_timings();
    }

    m_samples_accumulated += 1;

    timer.reset();

// This striding is just for speeding up
// We're basically drawing really big pixels here
#pragma omp parallel for collapse(2) schedule(dynamic, 1024)
    for (auto x = 0; x < width; x += m_stride_x) {
        for (auto y = 0; y < height; y += m_stride_y) {
            glm::vec4 color = luminance[y * width + x] / static_cast<float>(m_samples_accumulated);
            for (auto u = 0; u < m_stride_x; u++) {
                for (auto v = 0; v < m_stride_y; v++) {
                    m_pixels[(y + v) * width + (x + u)] = trac0r::pack_color_argb(color);
                }
            }
        }
    }

    if (m_print_perf)
        fmt::print("    {:<15} {:>10.3f} ms\n", "Pixel transfer", timer.elapsed());

    // std::vector<uint32_t> m_pixels_filtered;
    // m_pixels_filtered.resize(m_screen_width * m_screen_height, 0);
    // trac0r::box_filter(m_pixels, width, height, m_pixels_filtered);
    // m_pixels = m_pixels_filtered;
    //
    // if (m_print_perf)
    //     fmt::print("    {:<15} {:>10.3f} ms\n", "Image filtering", timer.elapsed());

    SDL_RenderClear(m_render);
    SDL_UpdateTexture(m_render_tex, 0, m_pixels.data(), width * sizeof(uint32_t));
    SDL_RenderCopy(m_render, m_render_tex, 0, 0);

    if (m_debug) {
        // Lots of debug info
        glm::vec2 mouse_rel_pos =
            Camera::screenspace_to_camspace(m_camera, mouse_pos.x, mouse_pos.y);
        glm::vec3 mouse_canvas_pos = Camera::camspace_to_worldspace(m_camera, mouse_rel_pos);

        auto fps_debug_info = "FPS: " + std::to_string(int(fps));
        auto scene_changing_info = "Samples : " + std::to_string(m_samples_accumulated);
        scene_changing_info += " Scene Changing: " + std::to_string(m_scene_changed);
        auto cam_look_debug_info = "Cam Look Mode: " + std::to_string(m_look_mode);
        auto cam_pos_debug_info = "Cam Pos: " + glm::to_string(Camera::pos(m_camera));
        auto cam_dir_debug_info = "Cam Dir: " + glm::to_string(Camera::dir(m_camera));
        auto cam_up_debug_info = "Cam Up: " + glm::to_string(Camera::up(m_camera));
        auto cam_fov_debug_info =
            "Cam FOV (H/V): " +
            std::to_string(int(glm::degrees(Camera::horizontal_fov(m_camera)))) + "/";
        cam_fov_debug_info += std::to_string(int(glm::degrees(Camera::vertical_fov(m_camera))));
        auto cam_canvas_center_pos_info =
            "Cam Canvas Center: " + glm::to_string(Camera::canvas_center_pos(m_camera));
        auto mouse_pos_screen_info = "Mouse Pos Screen Space: " + glm::to_string(mouse_pos);
        auto mouse_pos_relative_info = "Mouse Pos Cam Space: " + glm::to_string(mouse_rel_pos);
        auto mouse_pos_canvas_info =
            "Mouse Pos Canvas World Space: " + glm::to_string(mouse_canvas_pos);

        auto fps_debug_tex =
            trac0r::make_text(m_render, m_font, fps_debug_info, {200, 100, 100, 200});
        auto scene_changing_tex =
            trac0r::make_text(m_render, m_font, scene_changing_info, {200, 100, 100, 200});
        auto cam_look_debug_tex =
            trac0r::make_text(m_render, m_font, cam_look_debug_info, {200, 100, 100, 200});
        auto cam_pos_debug_tex =
            trac0r::make_text(m_render, m_font, cam_pos_debug_info, {200, 100, 100, 200});
        auto cam_dir_debug_tex =
            trac0r::make_text(m_render, m_font, cam_dir_debug_info, {200, 100, 100, 200});
        auto cam_up_debug_tex =
            trac0r::make_text(m_render, m_font, cam_up_debug_info, {200, 100, 100, 200});
        auto cam_fov_debug_tex =
            trac0r::make_text(m_render, m_font, cam_fov_debug_info, {200, 100, 100, 200});
        auto cam_canvas_center_pos_tex =
            trac0r::make_text(m_render, m_font, cam_canvas_center_pos_info, {200, 100, 100, 200});
        auto mouse_pos_screen_tex =
            trac0r::make_text(m_render, m_font, mouse_pos_screen_info, {200, 100, 100, 200});
        auto mouse_pos_relative_tex =
            trac0r::make_text(m_render, m_font, mouse_pos_relative_info, {200, 100, 100, 200});
        auto mouse_pos_canvas_tex =
            trac0r::make_text(m_render, m_font, mouse_pos_canvas_info, {200, 100, 100, 200});

        trac0r::render_text(m_render, fps_debug_tex, 10, 10);
        trac0r::render_text(m_render, scene_changing_tex, 10, 25);
        trac0r::render_text(m_render, cam_look_debug_tex, 10, 40);
        trac0r::render_text(m_render, cam_pos_debug_tex, 10, 55);
        trac0r::render_text(m_render, cam_dir_debug_tex, 10, 70);
        trac0r::render_text(m_render, cam_up_debug_tex, 10, 85);
        trac0r::render_text(m_render, cam_fov_debug_tex, 10, 100);
        trac0r::render_text(m_render, cam_canvas_center_pos_tex, 10, 115);
        trac0r::render_text(m_render, mouse_pos_screen_tex, 10, 130);
        trac0r::render_text(m_render, mouse_pos_relative_tex, 10, 145);
        trac0r::render_text(m_render, mouse_pos_canvas_tex, 10, 160);

        // Let's draw some debug to the display (such as AABBs)
        if (m_debug) {
            auto &accel_struct = Scene::accel_struct(m_scene);
            for (auto &shape : FlatStructure::shapes(accel_struct)) {
                auto &aabb = Shape::aabb(shape);
                const auto &verts = AABB::vertices(aabb);
                std::array<glm::i8vec2, 12> pairs;
                pairs[0] = {0, 1};
                pairs[1] = {1, 3};
                pairs[2] = {2, 3};
                pairs[3] = {0, 2};
                pairs[4] = {4, 5};
                pairs[5] = {5, 7};
                pairs[6] = {6, 7};
                pairs[7] = {4, 6};
                pairs[8] = {0, 4};
                pairs[9] = {1, 5};
                pairs[10] = {2, 6};
                pairs[11] = {3, 7};
                for (auto pair : pairs) {
                    auto ws1 = Camera::worldpoint_to_worldspace(m_camera, verts[pair[0]]);
                    auto ss1 = glm::i32vec2(0);
                    if (ws1 != glm::vec3(0)) {
                        auto cs1 = Camera::worldspace_to_camspace(m_camera, ws1);
                        ss1 = Camera::camspace_to_screenspace(m_camera, cs1);
                    }
                    auto ws2 = Camera::worldpoint_to_worldspace(m_camera, verts[pair[1]]);
                    auto ss2 = glm::i32vec2(0);
                    if (ws2 != glm::vec3(0)) {
                        auto cs2 = Camera::worldspace_to_camspace(m_camera, ws2);
                        ss2 = Camera::camspace_to_screenspace(m_camera, cs2);
                    }
                    if (ss1 != glm::i32vec2(0) && ss2 != glm::i32vec2(0)) {
                        aalineRGBA(m_render, ss1.x, ss1.y, ss2.x, ss2.y, 255, 255, 0, 200);
                    }
                }
            }
        }

        SDL_DestroyTexture(fps_debug_tex);
        SDL_DestroyTexture(scene_changing_tex);
        SDL_DestroyTexture(cam_look_debug_tex);
        SDL_DestroyTexture(cam_pos_debug_tex);
        SDL_DestroyTexture(cam_dir_debug_tex);
        SDL_DestroyTexture(cam_up_debug_tex);
        SDL_DestroyTexture(cam_fov_debug_tex);
        SDL_DestroyTexture(cam_canvas_center_pos_tex);
        SDL_DestroyTexture(mouse_pos_screen_tex);
        SDL_DestroyTexture(mouse_pos_relative_tex);
        SDL_DestroyTexture(mouse_pos_canvas_tex);
    }

    SDL_RenderPresent(m_render);

    if (m_print_perf) {
        fmt::print("    {:<15} {:>10.3f} ms\n", "Rendering", timer.elapsed());
        fmt::print("    {:<15} {:>10.3f} ms\n", "=> Budget", 1000.f / 60.f - total.peek());
        fmt::print("    {:<15} {:>10.3f} ms\n\n", "=> Total", total.peek());
    }

    m_frame_total += total.elapsed();
    if (m_benchmark_mode < 0 && m_max_frames != 0 && m_frame > m_max_frames) {
        auto filename = std::string("trac0r-") + std::to_string(m_max_frames) + std::string(".bmp");
        SDL_Surface *sshot = SDL_CreateRGBSurface(0, m_screen_width, m_screen_height, 32,
                                                  0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
        SDL_RenderReadPixels(m_render, NULL, SDL_PIXELFORMAT_ARGB8888, sshot->pixels, sshot->pitch);
        SDL_SaveBMP(sshot, filename.c_str());
        SDL_FreeSurface(sshot);
        shutdown();
    } else if (m_benchmark_mode > 0 && m_max_frames != 0 && m_frame > m_max_frames) {
        fmt::print("Benchmark results:\n");
        fmt::print("    {:<15} {:>10}\n", "Frames rendered", m_max_frames);
        fmt::print("    {:<15} {:>10.3f} ms\n", "Total runtime", m_frame_total);
        fmt::print("    {:<15} {:>10.3f} ms\n", "Avg. frame", m_frame_total / m_max_frames);
        fmt::print("    {:<15} {:>10.3f} FPS\n", "Avg. FPS",
                   1.f / ((m_frame_total / 1000.f) / m_max_frames));
        shutdown();
    }
}
Example #25
0
SDL_bool
DrawComposite(DrawState *s)
{
    SDL_Rect viewport, R;
    SDL_Texture *target;

    static SDL_bool blend_tested = SDL_FALSE;
    if (!blend_tested) {
        SDL_Texture *A, *B;
        Uint32 P;

        A = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1);
        SDL_SetTextureBlendMode(A, SDL_BLENDMODE_BLEND);

        B = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1);
        SDL_SetTextureBlendMode(B, SDL_BLENDMODE_BLEND);

        SDL_SetRenderTarget(s->renderer, A);
        SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x80);
        SDL_RenderFillRect(s->renderer, NULL);

        SDL_SetRenderTarget(s->renderer, B);
        SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00);
        SDL_RenderFillRect(s->renderer, NULL);
        SDL_RenderCopy(s->renderer, A, NULL, NULL);
        SDL_RenderReadPixels(s->renderer, NULL, SDL_PIXELFORMAT_ARGB8888, &P, sizeof(P));

        SDL_Log("Blended pixel: 0x%8.8X\n", P);

        SDL_DestroyTexture(A);
        SDL_DestroyTexture(B);
        blend_tested = SDL_TRUE;
    }

    SDL_RenderGetViewport(s->renderer, &viewport);

    target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h);
    SDL_SetTextureBlendMode(target, SDL_BLENDMODE_BLEND);
    SDL_SetRenderTarget(s->renderer, target);

    /* Draw the background.
       This is solid black so when the sprite is copied to it, any per-pixel alpha will be blended through.
     */
    SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00);
    SDL_RenderFillRect(s->renderer, NULL);

    /* Scale and draw the sprite */
    s->sprite_rect.w += s->scale_direction;
    s->sprite_rect.h += s->scale_direction;
    if (s->scale_direction > 0) {
        if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
            s->scale_direction = -1;
        }
    } else {
        if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
            s->scale_direction = 1;
        }
    }
    s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
    s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;

    SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect);

    SDL_SetRenderTarget(s->renderer, NULL);
    SDL_RenderCopy(s->renderer, s->background, NULL, NULL);

    SDL_SetRenderDrawBlendMode(s->renderer, SDL_BLENDMODE_BLEND);
    SDL_SetRenderDrawColor(s->renderer, 0xff, 0x00, 0x00, 0x80);
    R.x = 0;
    R.y = 0;
    R.w = 100;
    R.h = 100;
    SDL_RenderFillRect(s->renderer, &R);
    SDL_SetRenderDrawBlendMode(s->renderer, SDL_BLENDMODE_NONE);

    SDL_RenderCopy(s->renderer, target, NULL, NULL);
    SDL_DestroyTexture(target);

    /* Update the screen! */
    SDL_RenderPresent(s->renderer);
    return SDL_TRUE;
}
void
SDLRenderer::do_take_screenshot()
{
  // [Christoph] TODO: Yes, this method also takes care of the actual disk I/O. Split it?
  int width;
  int height;
  if (SDL_GetRendererOutputSize(m_renderer, &width, &height) != 0)
  {
    log_warning << "SDL_GetRenderOutputSize failed: " << SDL_GetError() << std::endl;
  }
  else
  {
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
    Uint32 rmask = 0xff000000;
    Uint32 gmask = 0x00ff0000;
    Uint32 bmask = 0x0000ff00;
    Uint32 amask = 0x000000ff;
#else
    Uint32 rmask = 0x000000ff;
    Uint32 gmask = 0x0000ff00;
    Uint32 bmask = 0x00ff0000;
    Uint32 amask = 0xff000000;
#endif
    SDL_Surface* surface = SDL_CreateRGBSurface(0, width, height, 32,
                                                rmask, gmask, bmask, amask);
    if (!surface)
    {
      log_warning << "SDL_CreateRGBSurface failed: " << SDL_GetError() << std::endl;
    }
    else
    {
      int ret = SDL_RenderReadPixels(m_renderer, NULL,
                                     SDL_PIXELFORMAT_ABGR8888,
                                     surface->pixels,
                                     surface->pitch);
      if (ret != 0)
      {
        log_warning << "SDL_RenderReadPixels failed: " << SDL_GetError() << std::endl;
      }
      else
      {
        // save screenshot
        static const std::string writeDir = PHYSFS_getWriteDir();
        static const std::string dirSep = PHYSFS_getDirSeparator();
        static const std::string baseName = "screenshot";
        static const std::string fileExt = ".bmp";
        std::string fullFilename;
        for (int num = 0; num < 1000; num++) {
          std::ostringstream oss;
          oss << baseName;
          oss << std::setw(3) << std::setfill('0') << num;
          oss << fileExt;
          std::string fileName = oss.str();
          fullFilename = writeDir + dirSep + fileName;
          if (!PHYSFS_exists(fileName.c_str())) {
            SDL_SaveBMP(surface, fullFilename.c_str());
            log_info << "Wrote screenshot to \"" << fullFilename << "\"" << std::endl;
            return;
          }
        }
        log_warning << "Did not save screenshot, because all files up to \"" << fullFilename << "\" already existed" << std::endl;
      }
    }
  }
}