Renderer::Renderer(int width, int height, const b2World *world) : width(width), height(height), font(NULL), world(world){ if(TTF_Init()==-1) { printf("TTF_Init: %s\n", TTF_GetError()); exit(2); } font = TTF_OpenFont("opensans.ttf", 16); SDL_Init( SDL_INIT_VIDEO ); if(SDL_GetNumVideoDisplays() > 1){ window = SDL_CreateWindow( "PinballBot", // window title SDL_WINDOWPOS_CENTERED_DISPLAY(1), // initial x position SDL_WINDOWPOS_CENTERED_DISPLAY(1), // initial y position this->width, // width, in pixels this->height, // height, in pixels SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI //enables retina support ); }else{ window = SDL_CreateWindow( "PinballBot", // window title SDL_WINDOWPOS_CENTERED, // initial x position SDL_WINDOWPOS_CENTERED, // initial y position this->width, // width, in pixels this->height, // height, in pixels SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI //enables retina support ); } if (window == nullptr) { printf("Could not create window: %s\n", SDL_GetError()); SDL_Quit(); return; } //updates the width and height if there's a high DPI and calc other vars afterwards SDL_GL_GetDrawableSize(window, &this->width, &this->height); oneMeterInPX = round(SCALING * this->height); /* one meter is equal to the height */ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_ADD); SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); //white background SDL_RenderClear(renderer); }
static void GetEnvironmentWindowPosition(int w, int h, int *x, int *y) { int display = GetVideoDisplay(); const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); const char *center = SDL_getenv("SDL_VIDEO_CENTERED"); if (window) { if (SDL_sscanf(window, "%d,%d", x, y) == 2) { return; } if (SDL_strcmp(window, "center") == 0) { center = window; } } if (center) { *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display); *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display); } }
// SDL1 doesn't support multiple displays, so the source is much shorter and doesn't need separate functions // makes sure the window will be full-screened on the right display and returns the SDL display index static int ScreenParmsHandleDisplayIndex( glimpParms_t parms ) { int displayIdx; if( parms.fullScreen > 0 ) { displayIdx = parms.fullScreen - 1; // first display for SDL is 0, in parms it's 1 } else // -2 == use current display { displayIdx = SDL_GetWindowDisplayIndex( window ); if( displayIdx < 0 ) // for some reason the display for the window couldn't be detected displayIdx = 0; } if( parms.fullScreen > SDL_GetNumVideoDisplays() ) { common->Warning( "Can't set fullscreen mode to display number %i, because SDL2 only knows about %i displays!", parms.fullScreen, SDL_GetNumVideoDisplays() ); return -1; } if( parms.fullScreen != glConfig.isFullscreen ) { // we have to switch to another display if( glConfig.isFullscreen ) { // if we're already in fullscreen mode but want to switch to another monitor // we have to go to windowed mode first to move the window.. SDL-oddity. SDL_SetWindowFullscreen( window, SDL_FALSE ); } // select display ; SDL_WINDOWPOS_UNDEFINED_DISPLAY() doesn't work. int x = SDL_WINDOWPOS_CENTERED_DISPLAY( displayIdx ); // move window to the center of selected display SDL_SetWindowPosition( window, x, x ); } return displayIdx; }
void OMW::Engine::createWindow(Settings::Manager& settings) { int screen = settings.getInt("screen", "Video"); int width = settings.getInt("resolution x", "Video"); int height = settings.getInt("resolution y", "Video"); bool fullscreen = settings.getBool("fullscreen", "Video"); bool windowBorder = settings.getBool("window border", "Video"); bool vsync = settings.getBool("vsync", "Video"); int antialiasing = settings.getInt("antialiasing", "Video"); int pos_x = SDL_WINDOWPOS_CENTERED_DISPLAY(screen), pos_y = SDL_WINDOWPOS_CENTERED_DISPLAY(screen); if(fullscreen) { pos_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen); pos_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen); } Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE; if(fullscreen) flags |= SDL_WINDOW_FULLSCREEN; if (!windowBorder) flags |= SDL_WINDOW_BORDERLESS; SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, settings.getBool("minimize on focus loss", "Video") ? "1" : "0"); checkSDLError(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24)); if (antialiasing > 0) { checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); } while (!mWindow) { mWindow = SDL_CreateWindow("OpenMW", pos_x, pos_y, width, height, flags); if (!mWindow) { // Try with a lower AA if (antialiasing > 0) { Log(Debug::Warning) << "Warning: " << antialiasing << "x antialiasing not supported, trying " << antialiasing/2; antialiasing /= 2; Settings::Manager::setInt("antialiasing", "Video", antialiasing); checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); continue; } else { std::stringstream error; error << "Failed to create SDL window: " << SDL_GetError(); throw std::runtime_error(error.str()); } } } setWindowIcon(); osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; SDL_GetWindowPosition(mWindow, &traits->x, &traits->y); SDL_GetWindowSize(mWindow, &traits->width, &traits->height); traits->windowName = SDL_GetWindowTitle(mWindow); traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS); traits->screenNum = SDL_GetWindowDisplayIndex(mWindow); // We tried to get rid of the hardcoding but failed: https://github.com/OpenMW/openmw/pull/1771 // Here goes kcat's quote: // It's ultimately a chicken and egg problem, and the reason why the code is like it was in the first place. // It needs a context to get the current attributes, but it needs the attributes to set up the context. // So it just specifies the same values that were given to SDL in the hopes that it's good enough to what the window eventually gets. traits->red = 8; traits->green = 8; traits->blue = 8; traits->alpha = 0; // set to 0 to stop ScreenCaptureHandler reading the alpha channel traits->depth = 24; traits->stencil = 8; traits->vsync = vsync; traits->doubleBuffer = true; traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow); osg::ref_ptr<SDLUtil::GraphicsWindowSDL2> graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits); if(!graphicsWindow->valid()) throw std::runtime_error("Failed to create GraphicsContext"); osg::ref_ptr<osg::Camera> camera = mViewer->getCamera(); camera->setGraphicsContext(graphicsWindow); camera->setViewport(0, 0, width, height); mViewer->realize(); mViewer->getEventQueue()->getCurrentEventState()->setWindowRectangle(0, 0, width, height); }
void OMW::Engine::createWindow(Settings::Manager& settings) { int screen = settings.getInt("screen", "Video"); int width = settings.getInt("resolution x", "Video"); int height = settings.getInt("resolution y", "Video"); bool fullscreen = settings.getBool("fullscreen", "Video"); bool windowBorder = settings.getBool("window border", "Video"); bool vsync = settings.getBool("vsync", "Video"); int antialiasing = settings.getInt("antialiasing", "Video"); int pos_x = SDL_WINDOWPOS_CENTERED_DISPLAY(screen), pos_y = SDL_WINDOWPOS_CENTERED_DISPLAY(screen); if(fullscreen) { pos_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen); pos_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(screen); } Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_RESIZABLE; if(fullscreen) flags |= SDL_WINDOW_FULLSCREEN; if (!windowBorder) flags |= SDL_WINDOW_BORDERLESS; SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, settings.getBool("minimize on focus loss", "Video") ? "1" : "0"); checkSDLError(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24)); if (antialiasing > 0) { checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1)); checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); } while (!mWindow) { mWindow = SDL_CreateWindow("OpenMW", pos_x, pos_y, width, height, flags); if (!mWindow) { // Try with a lower AA if (antialiasing > 0) { std::cout << "Note: " << antialiasing << "x antialiasing not supported, trying " << antialiasing/2 << std::endl; antialiasing /= 2; Settings::Manager::setInt("antialiasing", "Video", antialiasing); checkSDLError(SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antialiasing)); continue; } else { std::stringstream error; error << "Failed to create SDL window: " << SDL_GetError() << std::endl; throw std::runtime_error(error.str()); } } } setWindowIcon(); osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; SDL_GetWindowPosition(mWindow, &traits->x, &traits->y); SDL_GetWindowSize(mWindow, &traits->width, &traits->height); traits->windowName = SDL_GetWindowTitle(mWindow); traits->windowDecoration = !(SDL_GetWindowFlags(mWindow)&SDL_WINDOW_BORDERLESS); traits->screenNum = SDL_GetWindowDisplayIndex(mWindow); // FIXME: Some way to get these settings back from the SDL window? traits->red = 8; traits->green = 8; traits->blue = 8; traits->alpha = 0; // set to 0 to stop ScreenCaptureHandler reading the alpha channel traits->depth = 24; traits->stencil = 8; traits->vsync = vsync; traits->doubleBuffer = true; traits->inheritedWindowData = new SDLUtil::GraphicsWindowSDL2::WindowData(mWindow); osg::ref_ptr<SDLUtil::GraphicsWindowSDL2> graphicsWindow = new SDLUtil::GraphicsWindowSDL2(traits); if(!graphicsWindow->valid()) throw std::runtime_error("Failed to create GraphicsContext"); osg::ref_ptr<osg::Camera> camera = mViewer->getCamera(); camera->setGraphicsContext(graphicsWindow); camera->setViewport(0, 0, width, height); mViewer->realize(); }
int video_mode(int f, int w, int h) { //senquack /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); int stereo = config_get_d(CONFIG_STEREO) ? 1 : 0; int stencil = config_get_d(CONFIG_REFLECTION) ? 1 : 0; int buffers = config_get_d(CONFIG_MULTISAMPLE) ? 1 : 0; int samples = config_get_d(CONFIG_MULTISAMPLE); int vsync = config_get_d(CONFIG_VSYNC) ? 1 : 0; int hmd = config_get_d(CONFIG_HMD) ? 1 : 0; int highdpi = config_get_d(CONFIG_HIGHDPI) ? 1 : 0; int dpy = config_get_d(CONFIG_DISPLAY); int X = SDL_WINDOWPOS_CENTERED_DISPLAY(dpy); int Y = SDL_WINDOWPOS_CENTERED_DISPLAY(dpy); hmd_free(); if (window) { SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); } //senquack // SDL_GL_SetAttribute(SDL_GL_STEREO, stereo); //senquack - disabled drawing shadows and reflections on GCW Zero, don't need a stencil buffer: #ifdef GCWZERO SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0); #endif //senquack - don't need or want these on GCW Zero: #ifndef GCWZERO SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, buffers); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples); #endif /* Require 16-bit double buffer with 16-bit depth buffer. */ //senquack - GCW Zero port change SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); // SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); // SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6); // SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); // SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); // SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); //senquack SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); /* Try to set the currently specified mode. */ log_printf("Creating a window (%dx%d, %s)\n", w, h, (f ? "fullscreen" : "windowed")); //senquack DEBUG - DO NOT RUN - loads GLES2.0 for some reason // SDL_VideoInit(NULL); window = SDL_CreateWindow("", X, Y, w, h, SDL_WINDOW_OPENGL | (highdpi ? SDL_WINDOW_ALLOW_HIGHDPI : 0) | (f ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); if (window) { if ((context = SDL_GL_CreateContext(window))) { int buf, smp; SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buf); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &smp); /* * Work around SDL+WGL returning pixel formats below * minimum specifications instead of failing, thus * bypassing our fallback path. SDL tries to ensure that * WGL plays by the rules, but forgets about extended * context attributes such as multisample. See SDL * Bugzilla #77. */ if (buf < buffers || smp < samples) { log_printf("GL context does not meet minimum specifications\n"); SDL_GL_DeleteContext(context); context = NULL; } } } if (window && context) { set_window_title(TITLE); set_window_icon(ICON); /* * SDL_GetWindowSize can be unreliable when going fullscreen * on OSX (and possibly elsewhere). We should really be * waiting for a resize / size change event, but for now we're * doing this lazy thing instead. */ if (f) { SDL_DisplayMode dm; if (SDL_GetDesktopDisplayMode(video_display(), &dm) == 0) { video.window_w = dm.w; video.window_h = dm.h; // //senquack dm.format = SDL_PIXELFORMAT_RGBA8888; // dm.format = SDL_PIXELFORMAT_RGB565; dm.w = 320; dm.h = 240; dm.refresh_rate = 60; dm.driverdata = 0; SDL_SetWindowDisplayMode(window, &dm); printf("setting new video dm..\n"); SDL_GetCurrentDisplayMode(0, &dm); SDL_Log("Screen w: %d h: %d\n", dm.w, dm.h); SDL_Log("Screen bpp: %d\n", SDL_BITSPERPIXEL(dm.format)); SDL_Log("Screen dm: "); SDL_Log("\n\n"); SDL_Log("Vendor : %s\n", glGetString(GL_VENDOR)); SDL_Log("Renderer : %s\n", glGetString(GL_RENDERER)); SDL_Log("Version : %s\n", glGetString(GL_VERSION)); SDL_Log("Extensions : %s\n", glGetString(GL_EXTENSIONS)); SDL_Log("\n"); fflush(NULL); } } else { SDL_GetWindowSize(window, &video.window_w, &video.window_h); } if (highdpi) { SDL_GL_GetDrawableSize(window, &video.device_w, &video.device_h); } else { video.device_w = video.window_w; video.device_h = video.window_h; } video.device_scale = (float) video.device_h / (float) video.window_h; log_printf("Created a window (%u, %dx%d, %s)\n", SDL_GetWindowID(window), video.window_w, video.window_h, (f ? "fullscreen" : "windowed")); config_set_d(CONFIG_DISPLAY, video_display()); config_set_d(CONFIG_FULLSCREEN, f); config_set_d(CONFIG_WIDTH, video.window_w); config_set_d(CONFIG_HEIGHT, video.window_h); SDL_GL_SetSwapInterval(vsync); if (!glext_init()) return 0; glViewport(0, 0, video.device_w, video.device_h); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_BLEND); #if !ENABLE_OPENGLES glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); #endif glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_LEQUAL); /* If GL supports multisample, and SDL got a multisample buffer... */ if (glext_check("ARB_multisample")) { SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers); if (buffers) glEnable(GL_MULTISAMPLE); } /* Set up HMD display if requested. */ if (hmd) hmd_init(); /* Initialize screen snapshotting. */ snapshot_init(); video_show_cursor(); /* Grab input immediately in HMD mode. */ if (hmd_stat()) SDL_SetWindowGrab(window, SDL_TRUE); return 1; } /* If the mode failed, try it without stereo. */ else if (stereo) { config_set_d(CONFIG_STEREO, 0); return video_mode(f, w, h); } /* If the mode failed, try decreasing the level of multisampling. */ else if (buffers) { config_set_d(CONFIG_MULTISAMPLE, samples / 2); return video_mode(f, w, h); } /* If that mode failed, try it without reflections. */ else if (stencil) { config_set_d(CONFIG_REFLECTION, 0); return video_mode(f, w, h); } /* If THAT mode failed, punt. */ return 0; }
int main(int argc, char **argv) { ros::init(argc, argv, "oculus_image_viewer"); ros::NodeHandle node; image_transport::ImageTransport image_transport(node); std::string camera_topic = "/ardrone/front/image_raw"; ros::NodeHandle local_node("~"); local_node.getParam("camera_topic", camera_topic); ros::Subscriber sub_hmd_info = node.subscribe("/oculus/hmd_info", 1, &HMDInfoCallback); if (SDL_Init(SDL_INIT_VIDEO) < 0) { // Initialize SDL's Video subsystem std::cout << "Unable to initialize SDL"; return 1; } // Request opengl 4.4 context. SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); if (hmd_connected) { mainwindow = SDL_CreateWindow("oculus_viewer", SDL_WINDOWPOS_CENTERED_DISPLAY(hmd_info->DisplayId), SDL_WINDOWPOS_CENTERED_DISPLAY(hmd_info->DisplayId), hmd_info->HResolution, hmd_info->VResolution, SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_OPENGL); } else { // Create our window centered mainwindow = SDL_CreateWindow("oculus_viewer", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 800, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); // | SDL_WINDOW_RESIZABLE } if (!mainwindow) { // Die if creation failed std::cout << "SDL Error: " << SDL_GetError() << std::endl; SDL_Quit(); return 1; } bool quit = false; // image_transport::Subscriber sub_camera_image = image_transport.subscribe( // "/ardrone/front/image_raw", 1, &CameraImageCallback); image_transport::Subscriber sub_camera_image = image_transport.subscribe( camera_topic, 1, &CameraImageCallback); if (hmd_connected) { renderView = new Render::RenderView(mainwindow, maincontext, hmd_info->HResolution, hmd_info->VResolution); } else { renderView = new Render::RenderView(mainwindow, maincontext, 1280, 800); } ros::Rate rate(60); SDL_Event event; while (!quit && ros::ok()) { #if SHOWFPS==1 checkFrames(); #endif // if (hmd_connected) { // renderView->display(); // } else { // renderView->display(); // } renderView->display(); SDL_GL_SwapWindow(mainwindow); while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: quit = true; break; /*case SDL_WINDOWEVENT: if (event.window.event == SDL_WINDOWEVENT_RESIZED) renderView->reshape(event.window.data1, event.window.data2); break; */ case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_UP: renderView->increaseScale(0.05); break; case SDLK_DOWN: renderView->increaseScale(-0.05); break; case SDLK_LEFT: renderView->increaseDistortionConstant(-0.05); break; case SDLK_RIGHT: renderView->increaseDistortionConstant(0.05); break; case SDLK_j: renderView->increaseInterpupillarDistance(-0.01); break; case SDLK_k: renderView->increaseInterpupillarDistance(0.01); break; } break; } } #if SHOWFPS==1 renderedFrames++; #endif ros::spinOnce(); rate.sleep(); } // Delete our opengl context, destroy our window, and shutdown SDL SDL_GL_DeleteContext(maincontext); SDL_DestroyWindow(mainwindow); SDL_Quit(); delete (renderView); return 0; }
/** * @brief Initializes Game Window. * @param TITLE Set the title of the Window. * @param Background Set the background of the window. * @param SDL_SCREEN_FLAGS Start the window with given flags. * @return Returns 0 on success. */ int GameWindow::init( const char* TITLE , SDL_Color Background , int SDL_SCREEN_FLAGS ) { //If it already was inited, do not bother with it again if ( this->inited ) return 0; //Support for Resizeable windows //Check if the settings contain the option bool resizable; if ( this->content->Settings()->getBool ( "window" , "resizeable" , &resizable ) == true ) { //Evaluate if the option is set on if ( resizable ) { SDL_SCREEN_FLAGS |= SDL_WINDOW_RESIZABLE; } } //Support for fullscreen windows //Check if the settings contain the option bool fullscreen; if ( this->content->Settings()->getBool ( "window" , "fullscreen", &fullscreen ) == true ) { //Evaluate if the option is set on if ( fullscreen ) { SDL_SCREEN_FLAGS |= //Build option to use SDL_WINDOW_FULLSCREEN instead of DESKTOP #ifdef GAME_WINDOW_USE_WINDOW_FULLSCREEN SDL_WINDOW_FULLSCREEN; #else SDL_WINDOW_FULLSCREEN_DESKTOP; #endif } } int display = 0; this->content->Settings()->getInt ( "window" , "display" , &display ); //Set display to be rendered to SDL_DisplayMode display_mode; if ( SDL_GetDisplayMode( display , 0 , &display_mode ) != 0 ) { display = 0; std::cout << "An error has occurred" << std::endl << SDL_GetError() << std::endl; std::cout << "Defaulting to display index : " << display << std::endl; } int WIDTH = 800; if ( this->content->Settings()->getInt( "window" , "width" , &WIDTH ) == false ) { std::string native; if ( this->content->Settings()->get ( "window" , "width" , &native ) == true ) { if ( native == "native" ) { //Set height as native screen width SDL_DisplayMode dm; if ( SDL_GetDesktopDisplayMode( display , &dm ) == 0 ) { WIDTH = dm.w; } } } if ( WIDTH == 800 ) { std::cout << "Warning! Window width is set to default, 800px" << std::endl; } } int HIEGHT = 600; if ( this->content->Settings()->getInt( "window" , "height" , &HIEGHT ) == false ) { std::string native; if ( this->content->Settings()->get ( "window" , "height" , &native ) == true ) { if ( native == "native" ) { //Set height as native screen height SDL_DisplayMode dm; if ( SDL_GetDesktopDisplayMode( display , &dm ) == 0 ) { HIEGHT = dm.h; } } } if ( HIEGHT == 600 ) { std::cout << "Warning! Window height is set to default, 600px" << std::endl; } } //Create the window this->window = SDL_CreateWindow ( TITLE , SDL_WINDOWPOS_CENTERED_DISPLAY( display ) , SDL_WINDOWPOS_CENTERED_DISPLAY( display ) , WIDTH , HIEGHT , SDL_SCREEN_FLAGS ); //Set minimum size of window (640x480) SDL_SetWindowMinimumSize( this->window , 640, 480 ); SDL_SetWindowDisplayMode( this->window , &display_mode ); //Check if the window was created if ( this->window == nullptr ) { std::cout << "An error has occurred" << std::endl << SDL_GetError() << std::endl; std::cerr << SDL_GetError() << std::endl; return 1; } int render_flags = SDL_RENDERER_ACCELERATED; //Support for SDL_Render VSync //Check if the settings contain the option bool vsync; if ( this->content->Settings()->getBool ( "window" , "vsync" , &vsync ) ) { //Evaluate if the option is set on if ( vsync ) { //render_flags |= SDL_RENDERER_PRESENTVSYNC; this->CAP_FRAMES = true; } } int FRAME_LIMIT = display_mode.refresh_rate; if ( this->content->Settings()->getInt ( "window" , "framelimit" , &FRAME_LIMIT ) ) { std::cout << FRAME_LIMIT << std::endl; if ( FRAME_LIMIT > 0 ) { this->FRAME_LIMIT = FRAME_LIMIT; } else { std::cout << "Cannot set negative Frame Limit " << FRAME_LIMIT << std::endl; } } else { this->FRAME_LIMIT = FRAME_LIMIT; } bool windowborder = false; if ( this->content->Settings()->getBool ( "window" , "borderless" , &windowborder ) ) { if ( windowborder ) { SDL_SetWindowBordered( this->window , SDL_FALSE ); } } //Create Renderer this->renderer = SDL_CreateRenderer ( this->window , -1 , render_flags ); //Make sure it was created correctly if ( this->renderer == nullptr ) { std::cout << "An error has occurred" << std::endl << SDL_GetError() << std::endl; std::cerr << SDL_GetError() << std::endl; return 1; } //Set background colour this->background = Background; //Check if the System has a battery this->has_battery = etc::has_battery(); //Camera bnounds this->camera.setBounds( WIDTH , HIEGHT ); this->camera.setPosition( 0, 0 ); this->textures = graphics::TextureManager(this->renderer); this->content->Maps()->init(&(this->textures) , this->content->TileTypes()); this->content->load(); this->inited = true; //All done correctly return 0; }
// // SDLVideoDriver::InitGraphicsMode // // killough 11/98: New routine, for setting hires and page flipping // sf: now returns true if an error occurred // bool SDLVideoDriver::InitGraphicsMode() { // haleyjd 06/19/11: remember characteristics of last successful modeset static int fallback_w = 640; static int fallback_h = 480; static int fallback_w_flags = SDL_WINDOW_ALLOW_HIGHDPI; // SDL_RENDERER_SOFTWARE causes failures in creating renderer static int fallback_r_flags = SDL_RENDERER_TARGETTEXTURE; bool wantfullscreen = false; bool wantdesktopfs = false; bool wantvsync = false; bool wanthardware = false; bool wantframe = true; int v_w = 640; int v_h = 480; int v_displaynum = 0; int window_flags = SDL_WINDOW_ALLOW_HIGHDPI; // SDL_RENDERER_SOFTWARE causes failures in creating renderer int renderer_flags = SDL_RENDERER_TARGETTEXTURE; // haleyjd 04/11/03: "vsync" or page-flipping support if(use_vsync) wantvsync = true; // haleyjd 07/15/09: set defaults using geom string from configuration file I_ParseGeom(i_videomode, &v_w, &v_h, &wantfullscreen, &wantvsync, &wanthardware, &wantframe, &wantdesktopfs); // haleyjd 06/21/06: allow complete command line overrides but only // on initial video mode set (setting from menu doesn't support this) I_CheckVideoCmds(&v_w, &v_h, &wantfullscreen, &wantvsync, &wanthardware, &wantframe, &wantdesktopfs); // Wanting vsync forces framebuffer acceleration on if(wantvsync) { SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "1"); renderer_flags |= SDL_RENDERER_PRESENTVSYNC; } else if(wanthardware) SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "1"); else SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION, "0"); // haleyjd 10/27/09 if(!wantframe) window_flags |= SDL_WINDOW_BORDERLESS; if(displaynum < SDL_GetNumVideoDisplays()) v_displaynum = displaynum; else displaynum = 0; if(!(window = SDL_CreateWindow(ee_wmCaption, SDL_WINDOWPOS_CENTERED_DISPLAY(v_displaynum), SDL_WINDOWPOS_CENTERED_DISPLAY(v_displaynum), v_w, v_h, window_flags))) { // try 320x200w safety mode if(!(window = SDL_CreateWindow(ee_wmCaption, SDL_WINDOWPOS_CENTERED_DISPLAY(v_displaynum), SDL_WINDOWPOS_CENTERED_DISPLAY(v_displaynum), fallback_w, fallback_h, fallback_w_flags))) { // SDL_TODO: Trim fat from this error message I_FatalError(I_ERR_KILL, "I_SDLInitGraphicsMode: couldn't create window for mode %dx%d;\n" " Also failed to restore fallback mode %dx%d.\n" " Check your SDL video driver settings.\n", v_w, v_h, fallback_w, fallback_h); } // reset these for below population of video struct v_w = fallback_w; v_h = fallback_h; window_flags = fallback_w_flags; } #if EE_CURRENT_PLATFORM == EE_PLATFORM_MACOSX // this and the below #else block are done here as monitor video mode isn't // set when SDL_WINDOW_FULLSCREEN (sans desktop) is ORed in during window creation if(wantfullscreen) SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); #else if(wantfullscreen && wantdesktopfs) SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); else if(wantfullscreen) // && !wantdesktopfs SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN); #endif if(!(renderer = SDL_CreateRenderer(window, -1, renderer_flags))) { if(!(renderer = SDL_CreateRenderer(window, -1, fallback_r_flags))) { // SDL_TODO: Trim fat from this error message I_FatalError(I_ERR_KILL, "I_SDLInitGraphicsMode: couldn't create renderer for mode %dx%d;\n" " Also failed to restore fallback mode %dx%d.\n" " Check your SDL video driver settings.\n", v_w, v_h, fallback_w, fallback_h); } fallback_r_flags = renderer_flags; } // Record successful mode set for use as a fallback mode fallback_w = v_w; fallback_h = v_h; fallback_w_flags = window_flags; fallback_r_flags = renderer_flags; // haleyjd 10/09/05: keep track of fullscreen state fullscreen = !!(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN_DESKTOP); UpdateFocus(window); UpdateGrab(window); // check for letterboxing if(I_VideoShouldLetterbox(v_w, v_h)) { int hs = I_VideoLetterboxHeight(v_w); staticDestRect.x = 0; staticDestRect.y = static_cast<Sint16>(I_VideoLetterboxOffset(v_h, hs)); staticDestRect.w = static_cast<Uint16>(v_w); staticDestRect.h = static_cast<Uint16>(hs); video.width = v_w; video.height = hs; destrect = &staticDestRect; } else { video.width = v_w; video.height = v_h; destrect = nullptr; } video.bitdepth = 8; video.pixelsize = 1; UnsetPrimaryBuffer(); SetPrimaryBuffer(); // haleyjd 11/12/09: set surface palettes immediately I_SDLSetPaletteDirect(static_cast<byte *>(wGlobalDir.cacheLumpName("PLAYPAL", PU_CACHE))); return false; }
int video_mode(int f, int w, int h) { int stereo = config_get_d(CONFIG_STEREO) ? 1 : 0; int stencil = config_get_d(CONFIG_REFLECTION) ? 1 : 0; int buffers = config_get_d(CONFIG_MULTISAMPLE) ? 1 : 0; int samples = config_get_d(CONFIG_MULTISAMPLE); int vsync = config_get_d(CONFIG_VSYNC) ? 1 : 0; int hmd = config_get_d(CONFIG_HMD) ? 1 : 0; int highdpi = config_get_d(CONFIG_HIGHDPI) ? 1 : 0; int dpy = config_get_d(CONFIG_DISPLAY); int X = SDL_WINDOWPOS_CENTERED_DISPLAY(dpy); int Y = SDL_WINDOWPOS_CENTERED_DISPLAY(dpy); hmd_free(); if (window) { SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); } #if ENABLE_OPENGLES SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); #endif SDL_GL_SetAttribute(SDL_GL_STEREO, stereo); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencil); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, buffers); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples); /* Require 16-bit double buffer with 16-bit depth buffer. */ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); /* Try to set the currently specified mode. */ log_printf("Creating a window (%dx%d, %s)\n", w, h, (f ? "fullscreen" : "windowed")); window = SDL_CreateWindow("", X, Y, w, h, SDL_WINDOW_OPENGL | (highdpi ? SDL_WINDOW_ALLOW_HIGHDPI : 0) | (f ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); if (window) { if ((context = SDL_GL_CreateContext(window))) { int buf, smp; SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buf); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &smp); /* * Work around SDL+WGL returning pixel formats below * minimum specifications instead of failing, thus * bypassing our fallback path. SDL tries to ensure that * WGL plays by the rules, but forgets about extended * context attributes such as multisample. See SDL * Bugzilla #77. */ if (buf < buffers || smp < samples) { log_printf("GL context does not meet minimum specifications\n"); SDL_GL_DeleteContext(context); context = NULL; } } } if (window && context) { set_window_title(TITLE); set_window_icon(ICON); /* * SDL_GetWindowSize can be unreliable when going fullscreen * on OSX (and possibly elsewhere). We should really be * waiting for a resize / size change event, but for now we're * doing this lazy thing instead. */ if (f) { SDL_DisplayMode dm; if (SDL_GetDesktopDisplayMode(video_display(), &dm) == 0) { video.window_w = dm.w; video.window_h = dm.h; } } else { SDL_GetWindowSize(window, &video.window_w, &video.window_h); } if (highdpi) { SDL_GL_GetDrawableSize(window, &video.device_w, &video.device_h); } else { video.device_w = video.window_w; video.device_h = video.window_h; } video.device_scale = (float) video.device_h / (float) video.window_h; log_printf("Created a window (%u, %dx%d, %s)\n", SDL_GetWindowID(window), video.window_w, video.window_h, (f ? "fullscreen" : "windowed")); config_set_d(CONFIG_DISPLAY, video_display()); config_set_d(CONFIG_FULLSCREEN, f); config_set_d(CONFIG_WIDTH, video.window_w); config_set_d(CONFIG_HEIGHT, video.window_h); SDL_GL_SetSwapInterval(vsync); if (!glext_init()) return 0; glViewport(0, 0, video.device_w, video.device_h); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_BLEND); #if !ENABLE_OPENGLES glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); #endif glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_LEQUAL); /* If GL supports multisample, and SDL got a multisample buffer... */ if (glext_check("ARB_multisample")) { SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers); if (buffers) glEnable(GL_MULTISAMPLE); } /* Set up HMD display if requested. */ if (hmd) hmd_init(); /* Initialize screen snapshotting. */ snapshot_init(); video_show_cursor(); /* Grab input immediately in HMD mode. */ if (hmd_stat()) SDL_SetWindowGrab(window, SDL_TRUE); return 1; } /* If the mode failed, try it without stereo. */ else if (stereo) { config_set_d(CONFIG_STEREO, 0); return video_mode(f, w, h); } /* If the mode failed, try decreasing the level of multisampling. */ else if (buffers) { config_set_d(CONFIG_MULTISAMPLE, samples / 2); return video_mode(f, w, h); } /* If that mode failed, try it without reflections. */ else if (stencil) { config_set_d(CONFIG_REFLECTION, 0); return video_mode(f, w, h); } /* If THAT mode failed, punt. */ return 0; }
// // Set video mode // hal_bool SDL2_SetVideoMode(int width, int height, int fs, int mnum) { if(glcontext) { SDL_GL_DeleteContext(glcontext); glcontext = nullptr; } if(mainwindow) { SDL_DestroyWindow(mainwindow); mainwindow = nullptr; } Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_SHOWN; int x = SDL_WINDOWPOS_CENTERED_DISPLAY(mnum); int y = SDL_WINDOWPOS_CENTERED_DISPLAY(mnum); if(fs == 1) flags |= SDL_WINDOW_FULLSCREEN; // if dimensions are zero, then use fullscreen desktop if(!(width && height) || fs == -1) { x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(mnum); y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(mnum); flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; fs = -1; } // set GL attributes SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if(!(mainwindow = SDL_CreateWindow("Calico", x, y, width, height, flags))) { // Try resetting previous mode if(width != curscreenwidth || height != curscreenheight || fs != curfullscreen || mnum != curmonitornum) { return SDL2_SetVideoMode(curscreenwidth, curscreenheight, curfullscreen, curmonitornum); } else { hal_platform.fatalError("Failed to set video mode %dx%d (%s)", width, height, SDL_GetError()); } } // set window icon hal_platform.setIcon(); // create GL context if(!(glcontext = SDL_GL_CreateContext(mainwindow))) { hal_platform.fatalError("Failed to create GL context (%s)", SDL_GetError()); } // remember set state SDL_GetWindowSize(mainwindow, &curscreenwidth, &curscreenheight); curfullscreen = fs; curmonitornum = mnum; // calculate game subscreen geometry SDL2_calcSubRect(); // make current and set swap SDL_GL_MakeCurrent(mainwindow, glcontext); SDL2_ToggleGLSwap(HAL_TRUE); // wake up RB system RB_InitDefaultState(); // set orthonormal projection SDL2_setOrthoMode(curscreenwidth, curscreenheight); // update appstate maintenance hal_appstate.updateFocus(); hal_appstate.updateGrab(); return HAL_TRUE; }
int main(int argc, char** argv) { //stbi_set_flip_vertically_on_load(1); if(SDL_Init(SDL_INIT_EVERYTHING) != 0) { Log_Error("Could not init SDL"); Log_Error(SDL_GetError()); return 1; } SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1); SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); int32 window_display_index = 0; #if 1 window_display_index = 1; #endif SDL_Window* window = SDL_CreateWindow("Rituals", SDL_WINDOWPOS_CENTERED_DISPLAY(window_display_index), SDL_WINDOWPOS_CENTERED_DISPLAY(window_display_index), 1280, 720, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_MOUSE_FOCUS | SDL_WINDOW_INPUT_FOCUS); if(window == NULL) { Log_Error("Could not create window"); Log_Error(SDL_GetError()); return 1; } printf("%s \n", SDL_GetError()); SDL_GLContext glctx = SDL_GL_CreateContext(window); if(ogl_LoadFunctions() == ogl_LOAD_FAILED) { Log_Error("Could not load OpenGL 3.3 functions..."); return 1; } int ret = SDL_GL_SetSwapInterval(-1); { #define _check_gl_attribute(attr, val) int _##attr##_val; \ int _##attr##_success = SDL_GL_GetAttribute(attr, &_##attr##_val); \ gl_checks[gl_check_count++] = _##attr##_val == val; \ gl_names[gl_check_count - 1] = #attr; \ gl_vals[gl_check_count - 1] = _##attr##_val; \ gl_exp_vals[gl_check_count - 1] = val; //check if we got everything bool gl_checks[64]; char* gl_names[64]; int gl_vals[64]; int gl_exp_vals[64]; isize gl_check_count = 0; _check_gl_attribute(SDL_GL_RED_SIZE, 8); _check_gl_attribute(SDL_GL_GREEN_SIZE, 8); _check_gl_attribute(SDL_GL_BLUE_SIZE, 8); _check_gl_attribute(SDL_GL_ALPHA_SIZE, 8); _check_gl_attribute(SDL_GL_DOUBLEBUFFER, 1); _check_gl_attribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); _check_gl_attribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); _check_gl_attribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1); _check_gl_attribute(SDL_GL_ACCELERATED_VISUAL, 1); _check_gl_attribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); for(isize i = 0; i < gl_check_count; ++i) { printf("%s %s: wanted %d, got %d \n", gl_names[i], gl_checks[i] ? "succeeeded" : "failed", gl_exp_vals[i], gl_vals[i]); } } // Game initializiation game = Allocate(Game, 1); { game->window = window; game->state = Game_State_None; game->meta_arena = Allocate(Memory_Arena, 1); init_memory_arena(game->meta_arena, isz(Memory_Arena) * 10); game->game_arena = new_memory_arena(Kilobytes(64), game->meta_arena); game->asset_arena = new_memory_arena(Megabytes(512), game->meta_arena); game->temp_arena = new_memory_arena(Megabytes(64), game->meta_arena); game->play_arena = new_memory_arena(Megabytes(512), game->meta_arena); game->renderer_arena = new_memory_arena(Megabytes(32), game->meta_arena); game->base_path = SDL_GetBasePath(); game->base_path_length = strlen(game->base_path); game->input = Arena_Push_Struct(game->game_arena, Game_Input); game->input->scancodes = Arena_Push_Array(game->game_arena, int8, SDL_NUM_SCANCODES); game->input->keycodes = Arena_Push_Array(game->game_arena, int8, SDL_NUM_SCANCODES); game->input->mouse = Arena_Push_Array(game->game_arena, int8, 16); init_random(&game->r, time(NULL)); //TODO(will) load window settings from file game->window_size = v2i(1280, 720); game->scale = 1.0f; game->renderer = Arena_Push_Struct(game->game_arena, Renderer); renderer_init(game->renderer, game->renderer_arena); renderer = game->renderer; input = game->input; } load_assets(); bool running = true; SDL_Event event; glClearColor(0.1f, 0.1f, 0.1f, 1.0f); //glClearColor(1, 1, 1, 1); play_state->current_time = SDL_GetTicks(); play_state->prev_time = play_state->current_time; while(running) { uint64 start_ticks = SDL_GetTicks(); if(game->input->num_keys_down < 0) game->input->num_keys_down = 0; if(game->input->num_mouse_down < 0) game->input->num_mouse_down = 0; if(game->input->num_keys_down > 0) for(int64 i = 0; i < SDL_NUM_SCANCODES; ++i) { int8* t = game->input->scancodes + i; if(*t == State_Just_Released) { *t = State_Released; } else if(*t == State_Just_Pressed) { *t = State_Pressed; } t = game->input->keycodes + i; if(*t == State_Just_Released) { *t = State_Released; } else if(*t == State_Just_Pressed) { *t = State_Pressed; } } if(game->input->num_mouse_down > 0) for(int64 i = 0; i < 16; ++i) { int8* t = game->input->mouse + i; if(*t == State_Just_Released) { *t = State_Released; } else if(*t == State_Just_Pressed) { *t = State_Pressed; } } while(SDL_PollEvent(&event)) { //TODO(will) handle text input switch(event.type) { case SDL_QUIT: running = false; break; case SDL_WINDOWEVENT: update_screen(); break; case SDL_KEYDOWN: game->input->num_keys_down++; if(!event.key.repeat) { game->input->scancodes[event.key.keysym.scancode] = State_Just_Pressed; if(event.key.keysym.sym < SDL_NUM_SCANCODES) { game->input->keycodes[event.key.keysym.sym] = State_Just_Pressed; } } break; case SDL_KEYUP: game->input->num_keys_down--; if(!event.key.repeat) { game->input->scancodes[event.key.keysym.scancode] = State_Just_Released; if(event.key.keysym.sym < SDL_NUM_SCANCODES) { game->input->keycodes[event.key.keysym.sym] = State_Just_Released; } } break; case SDL_MOUSEBUTTONDOWN: game->input->num_mouse_down++; game->input->mouse[event.button.button] = State_Just_Pressed; break; case SDL_MOUSEBUTTONUP: game->input->num_mouse_down--; game->input->mouse[event.button.button] = State_Just_Released; break; } } int mx, my; SDL_GetMouseState(&mx, &my); input->mouse_x = mx; input->mouse_y = my; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); update(); SDL_GL_SwapWindow(window); uint64 frame_ticks = SDL_GetTicks() - start_ticks; //if(frame_ticks > 18) printf("Slow frame! %d\n", frame_ticks); } SDL_Quit(); return 0; }
bool Window::setWindow(int width, int height, WindowSettings *settings) { if (!graphics.get()) graphics.set(Module::getInstance<graphics::Graphics>(Module::M_GRAPHICS)); if (graphics.get() && graphics->isCanvasActive()) throw love::Exception("love.window.setMode cannot be called while a Canvas is active in love.graphics."); WindowSettings f; if (settings) f = *settings; f.minwidth = std::max(f.minwidth, 1); f.minheight = std::max(f.minheight, 1); f.display = std::min(std::max(f.display, 0), getDisplayCount() - 1); // Use the desktop resolution if a width or height of 0 is specified. if (width == 0 || height == 0) { SDL_DisplayMode mode = {}; SDL_GetDesktopDisplayMode(f.display, &mode); width = mode.w; height = mode.h; } Uint32 sdlflags = SDL_WINDOW_OPENGL; // On Android we always must have fullscreen type FULLSCREEN_TYPE_DESKTOP #ifdef LOVE_ANDROID f.fstype = FULLSCREEN_DESKTOP; #endif if (f.fullscreen) { if (f.fstype == FULLSCREEN_DESKTOP) sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP; else { sdlflags |= SDL_WINDOW_FULLSCREEN; SDL_DisplayMode mode = {0, width, height, 0, nullptr}; // Fullscreen window creation will bug out if no mode can be used. if (SDL_GetClosestDisplayMode(f.display, &mode, &mode) == nullptr) { // GetClosestDisplayMode will fail if we request a size larger // than the largest available display mode, so we'll try to use // the largest (first) mode in that case. if (SDL_GetDisplayMode(f.display, 0, &mode) < 0) return false; } width = mode.w; height = mode.h; } } if (f.resizable) sdlflags |= SDL_WINDOW_RESIZABLE; if (f.borderless) sdlflags |= SDL_WINDOW_BORDERLESS; if (f.highdpi) sdlflags |= SDL_WINDOW_ALLOW_HIGHDPI; int x = f.x; int y = f.y; if (f.useposition && !f.fullscreen) { // The position needs to be in the global coordinate space. SDL_Rect displaybounds = {}; SDL_GetDisplayBounds(f.display, &displaybounds); x += displaybounds.x; y += displaybounds.y; } else { if (f.centered) x = y = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display); else x = y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display); } close(); if (!createWindowAndContext(x, y, width, height, sdlflags, f.msaa, f.stencil, f.depth)) return false; // Make sure the window keeps any previously set icon. setIcon(icon.get()); // Make sure the mouse keeps its previous grab setting. setMouseGrab(mouseGrabbed); // Enforce minimum window dimensions. SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight); if ((f.useposition || f.centered) && !f.fullscreen) SDL_SetWindowPosition(window, x, y); SDL_RaiseWindow(window); SDL_GL_SetSwapInterval(f.vsync); // Check if adaptive vsync was requested but not supported, and fall back // to regular vsync if so. if (f.vsync == -1 && SDL_GL_GetSwapInterval() != -1) SDL_GL_SetSwapInterval(1); updateSettings(f, false); if (graphics.get()) { double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); graphics->setMode((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil); } #ifdef LOVE_ANDROID love::android::setImmersive(f.fullscreen); #endif return true; }
std::unique_ptr<os::OpenGLContext> SDLGraphicsOperations::createOpenGLContext(const os::OpenGLContextAttributes& attrs, uint32_t width, uint32_t height) { mprintf((" Initializing SDL video...\n")); #ifdef SCP_UNIX // Slight hack to make Mesa advertise S3TC support without libtxc_dxtn setenv("force_s3tc_enable", "true", 1); #endif if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { Error(LOCATION, "Couldn't init SDL video: %s", SDL_GetError()); return nullptr; } SDL_GL_SetAttribute(SDL_GL_RED_SIZE, attrs.red_size); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, attrs.green_size); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, attrs.blue_size); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, attrs.depth_size); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, attrs.stencil_size); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (attrs.multi_samples == 0) ? 0 : 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, attrs.multi_samples); mprintf((" Requested SDL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n", attrs.red_size, attrs.green_size, attrs.blue_size, attrs.depth_size, attrs.stencil_size, 1, attrs.multi_samples)); uint32_t windowflags = SDL_WINDOW_OPENGL; if (Cmdline_fullscreen_window) { windowflags |= SDL_WINDOW_BORDERLESS; } uint display = os_config_read_uint("Video", "Display", 0); SDL_Window* window = SDL_CreateWindow(Osreg_title, SDL_WINDOWPOS_CENTERED_DISPLAY(display), SDL_WINDOWPOS_CENTERED_DISPLAY(display), width, height, windowflags); if (window == nullptr) { Error(LOCATION, "Could not create window: %s\n", SDL_GetError()); return nullptr; } os_set_window(window); auto ctx = SDL_GL_CreateContext(os_get_window()); if (ctx == nullptr) { Error(LOCATION, "Could not create OpenGL Context: %s\n", SDL_GetError()); return nullptr; } int r, g, b, depth, stencil, db, fsaa_samples; SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b); SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth); SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &db); SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil); SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &fsaa_samples); mprintf((" Actual SDL Video values = R: %d, G: %d, B: %d, depth: %d, stencil: %d, double-buffer: %d, FSAA: %d\n", r, g, b, depth, stencil, db, fsaa_samples)); return std::unique_ptr<os::OpenGLContext>(new SDLOpenGLContext(ctx)); }
/* =============== GLimp_SetMode =============== */ static int GLimp_SetMode( int mode, bool fullscreen, bool noborder ) { const char *glstring; int perChannelColorBits; int alphaBits, depthBits, stencilBits; int samples; int i = 0; SDL_Surface *icon = nullptr; SDL_DisplayMode desktopMode; Uint32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; int x, y; GLenum glewResult; ri.Printf( PRINT_ALL, "Initializing OpenGL display\n" ); if ( r_allowResize->integer ) { flags |= SDL_WINDOW_RESIZABLE; } if ( r_centerWindow->integer ) { // center window on specified display x = SDL_WINDOWPOS_CENTERED_DISPLAY( r_displayIndex->integer ); y = SDL_WINDOWPOS_CENTERED_DISPLAY( r_displayIndex->integer ); } else { x = SDL_WINDOWPOS_UNDEFINED_DISPLAY( r_displayIndex->integer ); y = SDL_WINDOWPOS_UNDEFINED_DISPLAY( r_displayIndex->integer ); } icon = SDL_CreateRGBSurfaceFrom( ( void * ) CLIENT_WINDOW_ICON.pixel_data, CLIENT_WINDOW_ICON.width, CLIENT_WINDOW_ICON.height, CLIENT_WINDOW_ICON.bytes_per_pixel * 8, CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width, #ifdef Q3_LITTLE_ENDIAN 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #else 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF #endif ); if ( SDL_GetDesktopDisplayMode( r_displayIndex->integer, &desktopMode ) == 0 ) { displayAspect = ( float ) desktopMode.w / ( float ) desktopMode.h; ri.Printf( PRINT_ALL, "Display aspect: %.3f\n", displayAspect ); } else { Com_Memset( &desktopMode, 0, sizeof( SDL_DisplayMode ) ); ri.Printf( PRINT_ALL, "Cannot determine display aspect (%s), assuming 1.333\n", SDL_GetError() ); } ri.Printf( PRINT_ALL, "...setting mode %d:", mode ); if ( mode == -2 ) { // use desktop video resolution if ( desktopMode.h > 0 ) { glConfig.vidWidth = desktopMode.w; glConfig.vidHeight = desktopMode.h; } else { glConfig.vidWidth = 640; glConfig.vidHeight = 480; ri.Printf( PRINT_ALL, "Cannot determine display resolution, assuming 640x480\n" ); } glConfig.windowAspect = ( float ) glConfig.vidWidth / ( float ) glConfig.vidHeight; } else if ( !R_GetModeInfo( &glConfig.vidWidth, &glConfig.vidHeight, &glConfig.windowAspect, mode ) ) { ri.Printf( PRINT_ALL, " invalid mode\n" ); return RSERR_INVALID_MODE; } ri.Printf( PRINT_ALL, " %d %d\n", glConfig.vidWidth, glConfig.vidHeight ); Cvar_Set( "r_customwidth", va("%d", glConfig.vidWidth ) ); Cvar_Set( "r_customheight", va("%d", glConfig.vidHeight ) ); do { if ( glContext != nullptr ) { SDL_GL_DeleteContext( glContext ); glContext = nullptr; } if ( window != nullptr ) { SDL_GetWindowPosition( window, &x, &y ); ri.Printf( PRINT_DEVELOPER, "Existing window at %dx%d before being destroyed\n", x, y ); SDL_DestroyWindow( window ); window = nullptr; } // we come back here if we couldn't get a visual and there's // something we can switch off if ( fullscreen ) { flags |= SDL_WINDOW_FULLSCREEN; glConfig.isFullscreen = true; } else { if ( noborder ) { flags |= SDL_WINDOW_BORDERLESS; } glConfig.isFullscreen = false; } colorBits = r_colorbits->integer; if ( ( !colorBits ) || ( colorBits >= 32 ) ) { colorBits = 24; } alphaBits = r_alphabits->integer; if ( alphaBits < 0 ) { alphaBits = 0; } depthBits = r_depthbits->integer; if ( !depthBits ) { depthBits = 24; } stencilBits = r_stencilbits->integer; samples = r_ext_multisample->integer; for ( i = 0; i < 16; i++ ) { int testColorBits, testDepthBits, testStencilBits; // 0 - default // 1 - minus colorbits // 2 - minus depthbits // 3 - minus stencil if ( ( i % 4 ) == 0 && i ) { // one pass, reduce switch ( i / 4 ) { case 2: if ( colorBits == 24 ) { colorBits = 16; } break; case 1: if ( depthBits == 24 ) { depthBits = 16; } else if ( depthBits == 16 ) { depthBits = 8; } case 3: if ( stencilBits == 24 ) { stencilBits = 16; } else if ( stencilBits == 16 ) { stencilBits = 8; } } } testColorBits = colorBits; testDepthBits = depthBits; testStencilBits = stencilBits; if ( ( i % 4 ) == 3 ) { // reduce colorbits if ( testColorBits == 24 ) { testColorBits = 16; } } if ( ( i % 4 ) == 2 ) { // reduce depthbits if ( testDepthBits == 24 ) { testDepthBits = 16; } else if ( testDepthBits == 16 ) { testDepthBits = 8; } } if ( ( i % 4 ) == 1 ) { // reduce stencilbits if ( testStencilBits == 24 ) { testStencilBits = 16; } else if ( testStencilBits == 16 ) { testStencilBits = 8; } else { testStencilBits = 0; } } if ( testColorBits == 24 ) { perChannelColorBits = 8; } else { perChannelColorBits = 4; } SDL_GL_SetAttribute( SDL_GL_RED_SIZE, perChannelColorBits ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, perChannelColorBits ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, perChannelColorBits ); SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, alphaBits ); SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, testDepthBits ); SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, testStencilBits ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, samples ? 1 : 0 ); SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, samples ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); if ( !r_glAllowSoftware->integer ) { SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 ); } if ( r_glCoreProfile->integer || r_glDebugProfile->integer ) { int major = r_glMajorVersion->integer; int minor = r_glMinorVersion->integer; SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, major ); SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, minor ); if ( r_glCoreProfile->integer ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE ); } else { SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY ); } if ( r_glDebugProfile->integer ) { SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG ); } } window = SDL_CreateWindow( CLIENT_WINDOW_TITLE, x, y, glConfig.vidWidth, glConfig.vidHeight, flags ); if ( !window ) { ri.Printf( PRINT_DEVELOPER, "SDL_CreateWindow failed: %s\n", SDL_GetError() ); continue; } SDL_SetWindowIcon( window, icon ); glContext = SDL_GL_CreateContext( window ); if ( !glContext ) { ri.Printf( PRINT_DEVELOPER, "SDL_GL_CreateContext failed: %s\n", SDL_GetError() ); continue; } SDL_GL_SetSwapInterval( r_swapInterval->integer ); glConfig.colorBits = testColorBits; glConfig.depthBits = testDepthBits; glConfig.stencilBits = testStencilBits; ri.Printf( PRINT_ALL, "Using %d Color bits, %d depth, %d stencil display.\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits ); break; } if ( samples && ( !glContext || !window ) ) { r_ext_multisample->integer = 0; } } while ( ( !glContext || !window ) && samples ); SDL_FreeSurface( icon ); glewResult = glewInit(); if ( glewResult != GLEW_OK ) { // glewInit failed, something is seriously wrong ri.Error( ERR_FATAL, "GLW_StartOpenGL() - could not load OpenGL subsystem: %s", glewGetErrorString( glewResult ) ); } else { ri.Printf( PRINT_ALL, "Using GLEW %s\n", glewGetString( GLEW_VERSION ) ); } int GLmajor, GLminor; sscanf( ( const char * ) glGetString( GL_VERSION ), "%d.%d", &GLmajor, &GLminor ); if ( GLmajor < 2 || ( GLmajor == 2 && GLminor < 1 ) ) { // missing shader support, switch to 1.x renderer return RSERR_OLD_GL; } if ( GLmajor < 3 || ( GLmajor == 3 && GLminor < 2 ) ) { // shaders are supported, but not all GL3.x features ri.Printf( PRINT_ALL, "Using enhanced (GL3) Renderer in GL 2.x mode...\n" ); } else { ri.Printf( PRINT_ALL, "Using enhanced (GL3) Renderer in GL 3.x mode...\n" ); glConfig.driverType = GLDRV_OPENGL3; } GLimp_DetectAvailableModes(); glstring = ( char * ) glGetString( GL_RENDERER ); ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glstring ); return RSERR_OK; }
int SDLTest_CommonArg(SDLTest_CommonState * state, int index) { char **argv = state->argv; if (SDL_strcasecmp(argv[index], "--video") == 0) { ++index; if (!argv[index]) { return -1; } state->videodriver = argv[index]; return 2; } if (SDL_strcasecmp(argv[index], "--renderer") == 0) { ++index; if (!argv[index]) { return -1; } state->renderdriver = argv[index]; return 2; } if (SDL_strcasecmp(argv[index], "--gldebug") == 0) { state->gl_debug = 1; return 1; } if (SDL_strcasecmp(argv[index], "--info") == 0) { ++index; if (!argv[index]) { return -1; } if (SDL_strcasecmp(argv[index], "all") == 0) { state->verbose |= (VERBOSE_VIDEO | VERBOSE_MODES | VERBOSE_RENDER | VERBOSE_EVENT); return 2; } if (SDL_strcasecmp(argv[index], "video") == 0) { state->verbose |= VERBOSE_VIDEO; return 2; } if (SDL_strcasecmp(argv[index], "modes") == 0) { state->verbose |= VERBOSE_MODES; return 2; } if (SDL_strcasecmp(argv[index], "render") == 0) { state->verbose |= VERBOSE_RENDER; return 2; } if (SDL_strcasecmp(argv[index], "event") == 0) { state->verbose |= VERBOSE_EVENT; return 2; } return -1; } if (SDL_strcasecmp(argv[index], "--log") == 0) { ++index; if (!argv[index]) { return -1; } if (SDL_strcasecmp(argv[index], "all") == 0) { SDL_LogSetAllPriority(SDL_LOG_PRIORITY_VERBOSE); return 2; } if (SDL_strcasecmp(argv[index], "error") == 0) { SDL_LogSetPriority(SDL_LOG_CATEGORY_ERROR, SDL_LOG_PRIORITY_VERBOSE); return 2; } if (SDL_strcasecmp(argv[index], "system") == 0) { SDL_LogSetPriority(SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_PRIORITY_VERBOSE); return 2; } if (SDL_strcasecmp(argv[index], "audio") == 0) { SDL_LogSetPriority(SDL_LOG_CATEGORY_AUDIO, SDL_LOG_PRIORITY_VERBOSE); return 2; } if (SDL_strcasecmp(argv[index], "video") == 0) { SDL_LogSetPriority(SDL_LOG_CATEGORY_VIDEO, SDL_LOG_PRIORITY_VERBOSE); return 2; } if (SDL_strcasecmp(argv[index], "render") == 0) { SDL_LogSetPriority(SDL_LOG_CATEGORY_RENDER, SDL_LOG_PRIORITY_VERBOSE); return 2; } if (SDL_strcasecmp(argv[index], "input") == 0) { SDL_LogSetPriority(SDL_LOG_CATEGORY_INPUT, SDL_LOG_PRIORITY_VERBOSE); return 2; } return -1; } if (SDL_strcasecmp(argv[index], "--display") == 0) { ++index; if (!argv[index]) { return -1; } state->display = SDL_atoi(argv[index]); if (SDL_WINDOWPOS_ISUNDEFINED(state->window_x)) { state->window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display); state->window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(state->display); } if (SDL_WINDOWPOS_ISCENTERED(state->window_x)) { state->window_x = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display); state->window_y = SDL_WINDOWPOS_CENTERED_DISPLAY(state->display); } return 2; } if (SDL_strcasecmp(argv[index], "--fullscreen") == 0) { state->window_flags |= SDL_WINDOW_FULLSCREEN; state->num_windows = 1; return 1; } if (SDL_strcasecmp(argv[index], "--fullscreen-desktop") == 0) { state->window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; state->num_windows = 1; return 1; } if (SDL_strcasecmp(argv[index], "--windows") == 0) { ++index; if (!argv[index] || !SDL_isdigit(*argv[index])) { return -1; } if (!(state->window_flags & SDL_WINDOW_FULLSCREEN)) { state->num_windows = SDL_atoi(argv[index]); } return 2; } if (SDL_strcasecmp(argv[index], "--title") == 0) { ++index; if (!argv[index]) { return -1; } state->window_title = argv[index]; return 2; } if (SDL_strcasecmp(argv[index], "--icon") == 0) { ++index; if (!argv[index]) { return -1; } state->window_icon = argv[index]; return 2; } if (SDL_strcasecmp(argv[index], "--center") == 0) { state->window_x = SDL_WINDOWPOS_CENTERED; state->window_y = SDL_WINDOWPOS_CENTERED; return 1; } if (SDL_strcasecmp(argv[index], "--position") == 0) { char *x, *y; ++index; if (!argv[index]) { return -1; } x = argv[index]; y = argv[index]; while (*y && *y != ',') { ++y; } if (!*y) { return -1; } *y++ = '\0'; state->window_x = SDL_atoi(x); state->window_y = SDL_atoi(y); return 2; } if (SDL_strcasecmp(argv[index], "--geometry") == 0) { char *w, *h; ++index; if (!argv[index]) { return -1; } w = argv[index]; h = argv[index]; while (*h && *h != 'x') { ++h; } if (!*h) { return -1; } *h++ = '\0'; state->window_w = SDL_atoi(w); state->window_h = SDL_atoi(h); return 2; } if (SDL_strcasecmp(argv[index], "--min-geometry") == 0) { char *w, *h; ++index; if (!argv[index]) { return -1; } w = argv[index]; h = argv[index]; while (*h && *h != 'x') { ++h; } if (!*h) { return -1; } *h++ = '\0'; state->window_minW = SDL_atoi(w); state->window_minH = SDL_atoi(h); return 2; } if (SDL_strcasecmp(argv[index], "--max-geometry") == 0) { char *w, *h; ++index; if (!argv[index]) { return -1; } w = argv[index]; h = argv[index]; while (*h && *h != 'x') { ++h; } if (!*h) { return -1; } *h++ = '\0'; state->window_maxW = SDL_atoi(w); state->window_maxH = SDL_atoi(h); return 2; } if (SDL_strcasecmp(argv[index], "--logical") == 0) { char *w, *h; ++index; if (!argv[index]) { return -1; } w = argv[index]; h = argv[index]; while (*h && *h != 'x') { ++h; } if (!*h) { return -1; } *h++ = '\0'; state->logical_w = SDL_atoi(w); state->logical_h = SDL_atoi(h); return 2; } if (SDL_strcasecmp(argv[index], "--scale") == 0) { ++index; if (!argv[index]) { return -1; } state->scale = (float)SDL_atof(argv[index]); return 2; } if (SDL_strcasecmp(argv[index], "--depth") == 0) { ++index; if (!argv[index]) { return -1; } state->depth = SDL_atoi(argv[index]); return 2; } if (SDL_strcasecmp(argv[index], "--refresh") == 0) { ++index; if (!argv[index]) { return -1; } state->refresh_rate = SDL_atoi(argv[index]); return 2; } if (SDL_strcasecmp(argv[index], "--vsync") == 0) { state->render_flags |= SDL_RENDERER_PRESENTVSYNC; return 1; } if (SDL_strcasecmp(argv[index], "--noframe") == 0) { state->window_flags |= SDL_WINDOW_BORDERLESS; return 1; } if (SDL_strcasecmp(argv[index], "--resize") == 0) { state->window_flags |= SDL_WINDOW_RESIZABLE; return 1; } if (SDL_strcasecmp(argv[index], "--minimize") == 0) { state->window_flags |= SDL_WINDOW_MINIMIZED; return 1; } if (SDL_strcasecmp(argv[index], "--maximize") == 0) { state->window_flags |= SDL_WINDOW_MAXIMIZED; return 1; } if (SDL_strcasecmp(argv[index], "--grab") == 0) { state->window_flags |= SDL_WINDOW_INPUT_GRABBED; return 1; } if (SDL_strcasecmp(argv[index], "--rate") == 0) { ++index; if (!argv[index]) { return -1; } state->audiospec.freq = SDL_atoi(argv[index]); return 2; } if (SDL_strcasecmp(argv[index], "--format") == 0) { ++index; if (!argv[index]) { return -1; } if (SDL_strcasecmp(argv[index], "U8") == 0) { state->audiospec.format = AUDIO_U8; return 2; } if (SDL_strcasecmp(argv[index], "S8") == 0) { state->audiospec.format = AUDIO_S8; return 2; } if (SDL_strcasecmp(argv[index], "U16") == 0) { state->audiospec.format = AUDIO_U16; return 2; } if (SDL_strcasecmp(argv[index], "U16LE") == 0) { state->audiospec.format = AUDIO_U16LSB; return 2; } if (SDL_strcasecmp(argv[index], "U16BE") == 0) { state->audiospec.format = AUDIO_U16MSB; return 2; } if (SDL_strcasecmp(argv[index], "S16") == 0) { state->audiospec.format = AUDIO_S16; return 2; } if (SDL_strcasecmp(argv[index], "S16LE") == 0) { state->audiospec.format = AUDIO_S16LSB; return 2; } if (SDL_strcasecmp(argv[index], "S16BE") == 0) { state->audiospec.format = AUDIO_S16MSB; return 2; } return -1; } if (SDL_strcasecmp(argv[index], "--channels") == 0) { ++index; if (!argv[index]) { return -1; } state->audiospec.channels = (Uint8) SDL_atoi(argv[index]); return 2; } if (SDL_strcasecmp(argv[index], "--samples") == 0) { ++index; if (!argv[index]) { return -1; } state->audiospec.samples = (Uint16) SDL_atoi(argv[index]); return 2; } if ((SDL_strcasecmp(argv[index], "-h") == 0) || (SDL_strcasecmp(argv[index], "--help") == 0)) { /* Print the usage message */ return -1; } if (SDL_strcmp(argv[index], "-NSDocumentRevisionsDebugMode") == 0) { /* Debug flag sent by Xcode */ return 2; } return 0; }
int video_mode(int f, int w, int h) { int stereo = config_get_d(CONFIG_STEREO) ? 1 : 0; int stencil = config_get_d(CONFIG_REFLECTION) ? 1 : 0; int buffers = config_get_d(CONFIG_MULTISAMPLE) ? 1 : 0; int samples = config_get_d(CONFIG_MULTISAMPLE); int vsync = config_get_d(CONFIG_VSYNC) ? 1 : 0; int hmd = config_get_d(CONFIG_HMD) ? 1 : 0; int dpy = config_get_d(CONFIG_DISPLAY); int X = SDL_WINDOWPOS_CENTERED_DISPLAY(dpy); int Y = SDL_WINDOWPOS_CENTERED_DISPLAY(dpy); hmd_free(); if (window) { SDL_GL_DeleteContext(context); SDL_DestroyWindow(window); } SDL_GL_SetAttribute(SDL_GL_STEREO, stereo); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, stencil); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, buffers); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples); /* Require 16-bit double buffer with 16-bit depth buffer. */ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); /* Try to set the currently specified mode. */ window = SDL_CreateWindow("", X, Y, w, h, SDL_WINDOW_OPENGL | (f ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0)); if (window) { set_window_title(TITLE); set_window_icon(ICON); SDL_GetWindowSize(window, &w, &h); config_set_d(CONFIG_DISPLAY, video_display()); config_set_d(CONFIG_FULLSCREEN, f); config_set_d(CONFIG_WIDTH, w); config_set_d(CONFIG_HEIGHT, h); context = SDL_GL_CreateContext(window); SDL_GL_SetSwapInterval(vsync); if (!glext_init()) return 0; glViewport(0, 0, w, h); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glEnable(GL_BLEND); #if !ENABLE_OPENGLES glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); #endif glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_LEQUAL); /* If GL supports multisample, and SDL got a multisample buffer... */ if (glext_check("ARB_multisample")) { SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers); if (buffers) glEnable(GL_MULTISAMPLE); } /* Set up HMD display if requested. */ if (hmd) hmd_init(); /* Initialize screen snapshotting. */ snapshot_init(); video_show_cursor(); /* Grab input immediately in HMD mode. */ if (hmd_stat()) SDL_SetWindowGrab(window, SDL_TRUE); return 1; } /* If the mode failed, try it without stereo. */ else if (stereo) { config_set_d(CONFIG_STEREO, 0); return video_mode(f, w, h); } /* If the mode failed, try decreasing the level of multisampling. */ else if (buffers) { config_set_d(CONFIG_MULTISAMPLE, samples / 2); return video_mode(f, w, h); } /* If that mode failed, try it without reflections. */ else if (stencil) { config_set_d(CONFIG_REFLECTION, 0); return video_mode(f, w, h); } /* If THAT mode failed, punt. */ return 0; }