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; }
/** * @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 ); }
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); }
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); }
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; }
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) ); }
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; }
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; }
//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; }
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; }
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; }
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); }
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); }
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; }
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()); }
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; }
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++; }
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; }
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; } }
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; }
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); }
/** * \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); }
bool SDLRenderer::pixels(Uint8 pixels[], int pitch) { return SDL_RenderReadPixels(_renderer, nullptr, SDL_PIXELFORMAT_RGB24, pixels, pitch) == 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(); } }
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; } } } }