AVFrame *image_sdl_surface_to_frame(const SDL_Surface *src) { int size; AVFrame *frm = NULL; enum AVPixelFormat fmt; assert(src); assert(src->w > 4); assert(src->h > 4); switch(src->format->format) { case SDL_PIXELFORMAT_RGBA8888: fmt = AV_PIX_FMT_ABGR; break; case SDL_PIXELFORMAT_ARGB8888: fmt = AV_PIX_FMT_BGRA; break; case SDL_PIXELFORMAT_ABGR8888: fmt = AV_PIX_FMT_RGBA; break; case SDL_PIXELFORMAT_BGRA8888: fmt = AV_PIX_FMT_ARGB; break; case SDL_PIXELFORMAT_RGB24: case SDL_PIXELFORMAT_RGB888: fmt = AV_PIX_FMT_BGR24; break; case SDL_PIXELFORMAT_BGR888: case SDL_PIXELFORMAT_BGR24: fmt = AV_PIX_FMT_RGB24; break; default: sg_log_err("Unsupported SDL format %s.", SDL_GetPixelFormatName(src->format->format)); goto failed; } frm = pixel_alloc_frm((uint32_t)src->w, (uint32_t)src->h, fmt); if(!frm) goto failed; size = avpicture_get_size(fmt, src->w, src->h); if(size <= 0){ sg_log_err("avpicture_get_size(%d, %d, %d) %d", fmt, src->w, src->h, size); goto failed; } SDL_LockSurface(src); memcpy(frm->data[0], src->pixels, (size_t)size); SDL_UnlockSurface(src); frm->width = src->w; frm->height = src->h; frm->format = fmt; frm->pts = 0; return frm; failed: pixel_free_frm(&frm); return NULL; }
TextureBinary TextureLoaderSDLSurfaceImpl::load() { std::vector<float> pixels; std::size_t numChannels = 0; auto format = PixelFormat_None; switch (m_surface->format->format) { case SDL_PIXELFORMAT_RGB888: numChannels = 3; format = PixelFormat_RGB_32_F; break; case SDL_PIXELFORMAT_RGBA8888: numChannels = 4; format = PixelFormat_RGBA_32_F; break; default: Fail("Yet unsupported SDL Format"); } std::size_t numPixels = m_surface->w * m_surface->h * numChannels; pixels.reserve(numPixels); Uint8 r, g, b, a; for (auto y = m_surface->h - 1; y >= 0; y--) { for (auto x = 0; x < m_surface->w; x++) { auto offset = y * m_surface->pitch + x * m_surface->format->BytesPerPixel; uint8_t * pixel = &((uint8_t*)m_surface->pixels)[offset]; uint32_t value = *(uint32_t*)pixel; switch (m_surface->format->format) { case SDL_PIXELFORMAT_RGB888: SDL_GetRGB(value, m_surface->format, &r, &g, &b); pixels.push_back(r/255.0f); pixels.push_back(g/255.0f); pixels.push_back(b/255.0f); break; case SDL_PIXELFORMAT_RGBA8888: case SDL_PIXELFORMAT_ARGB8888: SDL_GetRGBA(value, m_surface->format, &r, &g, &b, &a); pixels.push_back(r/255.0f); pixels.push_back(g/255.0f); pixels.push_back(b/255.0f); pixels.push_back(a/255.0f); break; default: Fail(std::string("Yet unsupported SDL Format: ") + SDL_GetPixelFormatName(format)); } } } return TextureBinary(SurfaceBinary(std::move(pixels), m_surface->w, m_surface->h, format)); }
std::vector<SDL_DisplayMode> Display::get_fullscreen_video_modes() { std::vector<SDL_DisplayMode> video_modes; int num_displays = SDL_GetNumVideoDisplays(); log_info("number of displays: %1%", num_displays); for(int display = 0; display < num_displays; ++display) { int num_modes = SDL_GetNumDisplayModes(display); for (int i = 0; i < num_modes; ++i) { SDL_DisplayMode mode; if (SDL_GetDisplayMode(display, i, &mode) != 0) { log_error("failed to get display mode: %1%", SDL_GetError()); } else { log_debug("%1%x%2%@%3% %4%", mode.w, mode.h, mode.refresh_rate, SDL_GetPixelFormatName(mode.format)); video_modes.push_back(mode); } } } return video_modes; }
static void print_mode(const char *prefix, const SDL_DisplayMode *mode) { if (!mode) return; SDL_Log("%s: fmt=%s w=%d h=%d refresh=%d\n", prefix, SDL_GetPixelFormatName(mode->format), mode->w, mode->h, mode->refresh_rate); }
TextureLoaderSDLSurfaceImpl::TextureLoaderSDLSurfaceImpl(SDL_Surface * surface): m_surface(nullptr) { auto format = surface->format->format; switch (format) { case SDL_PIXELFORMAT_RGB888: m_surface = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGB888, 0); break; case SDL_PIXELFORMAT_RGBA8888: case SDL_PIXELFORMAT_ARGB8888: case SDL_PIXELFORMAT_ABGR8888: m_surface = SDL_ConvertSurfaceFormat(surface, SDL_PIXELFORMAT_RGBA8888, 0); break; default: Fail(std::string("Yet unsupported SDL Format: ") + SDL_GetPixelFormatName(format)); } }
int l_img_load_bta(lua_State *L) { btstring_t *fname; l_anim *a; bta_cell_t *c; uint32_t i; fname = _l_getFilePath(L, 1); l_anim_new(L); a = l_checkAnim(L, -1); a->bta = bta_read_bta(fname); c = bta_get_base(a->bta); a->loopData = gl_list_nx_create_empty(GL_ARRAY_LIST, NULL, NULL, l_loop_free, 1); if (a->loopData == NULL) { luaL_error(L, "Error creating loop data"); } for (i = 0; i < bta_getNumLoops(a->bta); i++) { l_loop_t *l; l = xzalloc(sizeof(l_loop_t)); l->anim = a; l->c_cell = 0; l->loopNumber = i; l->timer = 0; if (gl_list_nx_add_last(a->loopData, l) == NULL) { luaL_error(L, "Out of memory"); } } a->s = SDL_CreateRGBSurface(SDL_SWSURFACE, c->width, c->height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); debug("a->s->format = %s\n", SDL_GetPixelFormatName(a->s->format->format)); return 1; }
image_cv *sdl_surface_to_cv_mat(SDL_Surface *src) { int ch; enum pix_fmt pix_fmt; image_cv *res; assert(src); ch = image_sdl_channel(src); /* You can only use surface created by image_sdl_create*** as param src, otherwise, surface loaded from disk file could be other pixel formats. */ switch (src->format->format) { case SDL_PIXELFORMAT_ARGB8888: pix_fmt = PIXFMT_BGRA8888; break; case SDL_PIXELFORMAT_ABGR8888: pix_fmt = PIXFMT_RGBA8888; break; case SDL_PIXELFORMAT_RGB24: case SDL_PIXELFORMAT_RGB888: pix_fmt = PIXFMT_BGR888; break; case SDL_PIXELFORMAT_BGR24: case SDL_PIXELFORMAT_BGR888: pix_fmt = PIXFMT_RGB888; break; default: sg_log_err("Unsupported SDL format %s.", SDL_GetPixelFormatName(src->format->format)); return NULL; } res = image_cv_create_from_data(src->w, src->h, src->format->BitsPerPixel / 8, ch, src->pixels, src->w * src->h * src->format->BitsPerPixel / 8, pix_fmt); return res; }
// fonts are, for now, 2-color images with indexed pixel formats bool loadFont(const char *filename, font_t *font, Uint8 r, Uint8 g, Uint8 b) { font->surface = IMG_Load(filename); if (font->surface == NULL) { return false; } printf("loaded font %s, pixel format = %s\n", filename, SDL_GetPixelFormatName(font->surface->format->format)); printf("colors in palette = %d\n", font->surface->format->palette->ncolors); // find the background colour and set it as the colour key Uint32 bgIndex = SDL_MapRGB(font->surface->format, r, g, b); SDL_SetColorKey(font->surface, SDL_TRUE, bgIndex); printf("background index = %d\n", bgIndex); // store a pointer to the foreground colour's palette entry so we can update it when we blit the string font->fgColor = &font->surface->format->palette->colors[bgIndex == 1 ? 0 : 1]; // assume 32x8 chars font->charWidth = font->surface->w / 32; font->charHeight = font->surface->h / 8; return true; }
void KPSdl2UserInterface::OpenWindow(int /* argc */ , char ** /* argv */) { auto flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; SDL_version compiled; SDL_version linked; std::stringstream message; SDL_VERSION(&compiled); SDL_GetVersion(&linked); BLogger::Log("SDL UserInterface initialization"); BLogger::Log("SDL linked version: ", static_cast<unsigned int>(linked.major), '.', static_cast<unsigned int>(linked.minor), '.', static_cast<unsigned int>(linked.patch)); BLogger::Log("SDL compiled version: ", static_cast<unsigned int>(compiled.major), '.', static_cast<unsigned int>(compiled.minor), '.', static_cast<unsigned int>(compiled.patch)); BLogger::Log("SDL Header version: ", SDL_MAJOR_VERSION, '.', SDL_MINOR_VERSION, '.', SDL_PATCHLEVEL); BLogger::Log("SDL Revision: ", SDL_GetRevision()); auto pVersion = Mix_Linked_Version(); BLogger::Log("SDL_mixer Linked version: ", static_cast<unsigned int>(pVersion->major), '.', static_cast<unsigned int>(pVersion->minor), '.', static_cast<unsigned int>(pVersion->patch)); BLogger::Log("SDL_mixer Header version: ", MIX_MAJOR_VERSION, '.', MIX_MINOR_VERSION, '.', MIX_PATCHLEVEL); // Set OpenGL's context to 2.1 subset functionality profile. SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); // Open OpenGL Window with SDL if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0) { message << "Error in SDL_Init: " << SDL_GetError(); SDL_Quit(); throw std::runtime_error(message.str()); } if (config->FullScreen) { flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } if (!IsWindowResolutionSupported(config->ScreenXResolution, (config->ScreenXResolution * 3) / 4)) { config->ScreenXResolution = 640; } window = SDL_CreateWindow( GetWindowTitle().c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, config->ScreenXResolution, (config->ScreenXResolution * 3) / 4, flags); if (window == nullptr) { message << "Error in SDL_CreateWindow: " << SDL_GetError(); SDL_Quit(); throw std::runtime_error(message.str()); } // We intentionally do not use the SDL renderer. It only supports 2D // and on Windows would use DirectX and not the OpenGL backend. // Instead the OpenGL renderer is used together with ligGLEW. glContext = SDL_GL_CreateContext(window); if (glContext == nullptr) { message << "Error in SDL_GL_CreateContext: " << SDL_GetError(); SDL_Quit(); throw std::runtime_error(message.str()); } // Do updates synchronized with VSync SDL_GL_SetSwapInterval(1); auto glewReturn = glewInit(); if (glewReturn != GLEW_OK) { message << "Error in glewInit: " << glewGetErrorString(glewReturn); SDL_Quit(); throw std::runtime_error(message.str()); } BLogger::Log("GLEW version: ", glewGetString(GLEW_VERSION)); SDL_DisplayMode mode; SDL_GetWindowDisplayMode(window, &mode); BLogger::Log("SDL pixel format: ", SDL_GetPixelFormatName(mode.format)); BLogger::Log("SDL refresh rate: ", mode.refresh_rate, " Hz"); DebugPrintOpenGLVersion(); DebugPrintOpenGLContextVersion(); InitializeAudio(config->TextureName); InitializeAfterOpen(); }
/** * @brief Call to SDL_GetPixelFormatName * * @sa http://wiki.libsdl.org/moin.fcg/SDL_GetPixelFormatName */ int pixels_getPixelFormatName(void *arg) { const char *unknownFormat = "SDL_PIXELFORMAT_UNKNOWN"; const char *error; int i; Uint32 format; char* result; /* Blank/undefined format */ format = 0; SDLTest_Log("RGB Format: %s (%u)", unknownFormat, format); /* Get name of format */ result = (char *)SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); SDLTest_AssertCheck(SDL_strcmp(result, unknownFormat) == 0, "Verify result text; expected: %s, got %s", unknownFormat, result); } /* RGB formats */ for (i = 0; i < _numRGBPixelFormats; i++) { format = _RGBPixelFormats[i]; SDLTest_Log("RGB Format: %s (%u)", _RGBPixelFormatsVerbose[i], format); /* Get name of format */ result = (char *)SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); SDLTest_AssertCheck(SDL_strcmp(result, _RGBPixelFormatsVerbose[i]) == 0, "Verify result text; expected: %s, got %s", _RGBPixelFormatsVerbose[i], result); } } /* Non-RGB formats */ for (i = 0; i < _numNonRGBPixelFormats; i++) { format = _nonRGBPixelFormats[i]; SDLTest_Log("non-RGB Format: %s (%u)", _nonRGBPixelFormatsVerbose[i], format); /* Get name of format */ result = (char *)SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName()"); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty"); SDLTest_AssertCheck(SDL_strcmp(result, _nonRGBPixelFormatsVerbose[i]) == 0, "Verify result text; expected: %s, got %s", _nonRGBPixelFormatsVerbose[i], result); } } /* Negative cases */ /* Invalid Formats */ SDL_ClearError(); SDLTest_AssertPass("Call to SDL_ClearError()"); for (i = 0; i < _numInvalidPixelFormats; i++) { format = _invalidPixelFormats[i]; result = (char *)SDL_GetPixelFormatName(format); SDLTest_AssertPass("Call to SDL_GetPixelFormatName(%u)", format); SDLTest_AssertCheck(result != NULL, "Verify result is not NULL"); if (result != NULL) { SDLTest_AssertCheck(result[0] != '\0', "Verify result is non-empty; got: %s", result); SDLTest_AssertCheck(SDL_strcmp(result, _invalidPixelFormatsVerbose[i]) == 0, "Validate name is UNKNOWN, expected: '%s', got: '%s'", _invalidPixelFormatsVerbose[i], result); } error = SDL_GetError(); SDLTest_AssertPass("Call to SDL_GetError()"); SDLTest_AssertCheck(error != NULL && error[0] != '\0', "Validate that error message is empty"); } return TEST_COMPLETED; }
int SDLFrontend::init (int width, int height, bool fullscreen, EventHandler &eventHandler) { if (width == -1 && height == -1) fullscreen = true; info(LOG_CLIENT, String::format("initializing: %i:%i - fullscreen: %s", width, height, fullscreen ? "true" : "false")); INIT_Subsystem(SDL_INIT_VIDEO, true); INIT_Subsystem(SDL_INIT_JOYSTICK, false); INIT_Subsystem(SDL_INIT_GAMECONTROLLER, false); INIT_Subsystem(SDL_INIT_HAPTIC, false); initJoystickAndHaptic(); SDL_DisplayMode displayMode; SDL_GetDesktopDisplayMode(0, &displayMode); const char *name = SDL_GetPixelFormatName(displayMode.format); info(LOG_CLIENT, String::format("current desktop mode: %dx%d@%dHz (%s)", displayMode.w, displayMode.h, displayMode.refresh_rate, name)); if (width == -1) width = 800;//displayMode.w; if (height == -1) height = 480; //displayMode.h; setGLAttributes(); setHints(); int doubleBuffered = 0; SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &doubleBuffered); info(LOG_CLIENT, String::format("doublebuffer: %s", doubleBuffered ? "activated" : "disabled")); int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; #ifdef __IPHONEOS__ flags |= SDL_WINDOW_RESIZABLE; #endif #if 1 //defined __IPHONEOS__ || defined __ANDROID__ if (fullscreen) flags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS; #else if (fullscreen) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_BORDERLESS; #endif const int videoDrivers = SDL_GetNumVideoDrivers(); for (int i = 0; i < videoDrivers; ++i) { info(LOG_CLIENT, String::format("available driver: %s", SDL_GetVideoDriver(i))); } info(LOG_CLIENT, String::format("driver: %s", SDL_GetCurrentVideoDriver())); const int displays = SDL_GetNumVideoDisplays(); info(LOG_CLIENT, String::format("found %i display(s)", displays)); if (fullscreen && displays > 1) { width = displayMode.w; height = displayMode.h; info(LOG_CLIENT, String::format("use fake fullscreen for the first display: %i:%i", width, height)); } _window = SDL_CreateWindow(Singleton<Application>::getInstance().getName().c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, flags); if (!_window) { sdlCheckError(); return -1; } SDL_DisableScreenSaver(); initRenderer(); resetColor(); GLContext::get().init(); if (SDL_SetWindowBrightness(_window, 1.0f) == -1) sdlCheckError(); if (Config.isGrabMouse() && (!fullscreen || displays > 1)) { SDL_SetWindowGrab(_window, SDL_TRUE); } int screen = 0; int modes = SDL_GetNumDisplayModes(screen); info(LOG_CLIENT, "possible display modes:"); for (int i = 0; i < modes; i++) { SDL_GetDisplayMode(screen, i, &displayMode); name = SDL_GetPixelFormatName(displayMode.format); info(LOG_CLIENT, String::format("%dx%d@%dHz %s", displayMode.w, displayMode.h, displayMode.refresh_rate, name)); } // some platforms may override or hardcode the resolution - so // we have to query it here to get the actual resolution SDL_GetWindowSize(_window, &width, &height); if (SDL_SetRelativeMouseMode(SDL_TRUE) == -1) error(LOG_CLIENT, "no relative mouse mode support"); SDL_ShowCursor(0); info(LOG_CLIENT, String::format("actual resolution: %dx%d", width, height)); setVSync(ConfigManager::get().isVSync()); const int initState = IMG_Init(IMG_INIT_PNG); if (!(initState & IMG_INIT_PNG)) { sdlCheckError(); System.exit("No png support", 1); } _width = width; _height = height; updateViewport(0, 0, getWidth(), getHeight()); onInit(); _eventHandler = &eventHandler; _eventHandler->registerObserver(_console.get()); _eventHandler->registerObserver(this); info(LOG_CLIENT, "init the shader manager"); ShaderManager::get().init(); if (!Config.isSoundEnabled()) { info(LOG_CLIENT, "sound disabled"); } else if (!SoundControl.init(true)) { error(LOG_CLIENT, "sound initialization failed"); } return 0; }
int inline LOBJECT_METHOD(getName, SDL_PixelFormat * format){ state.push_string(SDL_GetPixelFormatName(format->format)); return 1; }
static int Init() { nInitedSubsytems = SDL_WasInit(SDL_INIT_VIDEO); if (!(nInitedSubsytems & SDL_INIT_VIDEO)) { SDL_InitSubSystem(SDL_INIT_VIDEO); } nUseBlitter = 0; nGameWidth = nVidImageWidth; nGameHeight = nVidImageHeight; nRotateGame = 0; //nVidRotationAdjust = 1; // add_shin if (bDrvOkay) { // Get the game screen size BurnDrvGetVisibleSize(&nGameWidth, &nGameHeight); printf( "vid_sdlfx.Init: nGame: %ix%i", nGameWidth, nGameHeight ); if (BurnDrvGetFlags() & BDF_ORIENTATION_VERTICAL) { if (nVidRotationAdjust & 1) { int n = nGameWidth; nGameWidth = nGameHeight; nGameHeight = n; nRotateGame |= (nVidRotationAdjust & 2); } else { nRotateGame |= 1; } } if (BurnDrvGetFlags() & BDF_ORIENTATION_FLIPPED) { nRotateGame ^= 2; } } nSize = VidSoftFXGetZoom(nUseBlitter); bVidScanlines = 0; // !!! if( ( sdlFramebuf = SDL_SetVideoMode(nGameWidth * nSize, nGameHeight * nSize, 0, SDL_RESIZABLE | SDL_HWSURFACE ) ) == NULL ) return 1; printf("android_sdlfx.Init: SDL_SetVideoMode( %i, %i )", nGameWidth * nSize, nGameHeight * nSize ); printf("android_sdlfx.Init: sdlFramebuf PixelFormat = %s", SDL_GetPixelFormatName( SDL_MasksToPixelFormatEnum( sdlFramebuf->format->BitsPerPixel, sdlFramebuf->format->Rmask, sdlFramebuf->format->Gmask, sdlFramebuf->format->Bmask, sdlFramebuf->format->Amask) ) ); printf("android_sdlfx.Init: ( %i, %u, %u, %u, %u )", sdlFramebuf->format->BitsPerPixel, sdlFramebuf->format->Rmask, sdlFramebuf->format->Gmask, sdlFramebuf->format->Bmask, sdlFramebuf->format->Amask ); SDL_SetClipRect(sdlFramebuf, NULL); // Initialize the buffer surfaces BlitFXInit(); if (VidSoftFXInit(nUseBlitter, nRotateGame)) { if (VidSoftFXInit(0, nRotateGame)) { Exit(); return 1; } } printf( "vid_sdlfx.Init: nRotateGame=%i", nRotateGame ); return 0; }
const std::string PIXEL_FORMAT_NAME ( uint32 format ) { return std::string (SDL_GetPixelFormatName ( format ) ); }
int lite3d_video_open(lite3d_video_settings *settings, int hideConsole) { uint32_t windowFlags; SDL_DisplayMode displayMode; SDL_assert(settings); #ifdef PLATFORM_Windows if (hideConsole) { FreeConsole(); } #endif 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, settings->colorBits > 24 ? 8 : 0); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, 16); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); #ifndef GLES /* Specify openGL context */ if (settings->FSAA > 1) { SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, settings->FSAA); } if (settings->glProfile == LITE3D_GL_PROFILE_CORE) { SDL_LogInfo( SDL_LOG_CATEGORY_APPLICATION, "Setting Core OpenGL Profile"); SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); set_opengl_version(settings); } else if (settings->glProfile == LITE3D_GL_PROFILE_COMPATIBILITY) { SDL_LogInfo( SDL_LOG_CATEGORY_APPLICATION, "Setting Compatibility OpenGL Profile"); SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); set_opengl_version(settings); } else { SDL_LogInfo( SDL_LOG_CATEGORY_APPLICATION, "Using Default OpenGL Profile"); SDL_LogInfo( SDL_LOG_CATEGORY_APPLICATION, "Using Default OpenGL Version"); } #endif #ifdef WITH_GLES2 SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #elif WITH_GLES3 SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #endif windowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN; if (settings->fullscreen) { windowFlags |= SDL_WINDOW_FULLSCREEN; windowFlags |= SDL_WINDOW_BORDERLESS; } if (settings->screenWidth == 0 || settings->screenHeight == 0) { if (!lite3d_video_get_display_size( &settings->screenWidth, &settings->screenHeight)) { SDL_LogWarn( SDL_LOG_CATEGORY_APPLICATION, "lite3d_video_get_display_size failed"); return LITE3D_FALSE; } } /* setup render window */ gRenderWindow = SDL_CreateWindow( settings->caption, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, settings->screenWidth, settings->screenHeight, windowFlags); if (!gRenderWindow) { SDL_LogCritical( SDL_LOG_CATEGORY_APPLICATION, "%s: SDL_CreateWindow failed..", LITE3D_CURRENT_FUNCTION); return LITE3D_FALSE; } SDL_LogInfo( SDL_LOG_CATEGORY_APPLICATION, "%s: render window created %dx%d (%s)", LITE3D_CURRENT_FUNCTION, settings->screenWidth, settings->screenHeight, settings->fullscreen ? "fullscreen" : "windowed"); /* Create an OpenGL context associated with the window. */ gGLContext = SDL_GL_CreateContext(gRenderWindow); if (!gGLContext) { SDL_LogCritical( SDL_LOG_CATEGORY_APPLICATION, "%s: GL Context create failed..", LITE3D_CURRENT_FUNCTION); return LITE3D_FALSE; } /* set gl context */ SDL_GL_MakeCurrent(gRenderWindow, gGLContext); SDL_GetWindowDisplayMode(gRenderWindow, &displayMode); SDL_LogInfo( SDL_LOG_CATEGORY_APPLICATION, "%s: selected pixel format: %d bpp, %s", LITE3D_CURRENT_FUNCTION, SDL_BITSPERPIXEL(displayMode.format), SDL_GetPixelFormatName(displayMode.format)); SDL_GL_SetSwapInterval(settings->vsync ? 1 : 0); if (!init_gl_extensions(settings)) { SDL_LogWarn( SDL_LOG_CATEGORY_APPLICATION, "init_gl_extensions failed"); lite3d_video_close(); return LITE3D_FALSE; } if (!settings->hidden) { SDL_ShowWindow(gRenderWindow); } return LITE3D_TRUE; }
static int GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata; GLES_TextureData *data; GLint internalFormat; GLenum format, type; int texture_w, texture_h; GLenum result; switch (texture->format) { case SDL_PIXELFORMAT_RGB24: internalFormat = GL_RGB; format = GL_RGB; type = GL_UNSIGNED_BYTE; break; case SDL_PIXELFORMAT_BGR888: case SDL_PIXELFORMAT_ABGR8888: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_BYTE; break; case SDL_PIXELFORMAT_RGB565: internalFormat = GL_RGB; format = GL_RGB; type = GL_UNSIGNED_SHORT_5_6_5; break; case SDL_PIXELFORMAT_RGBA5551: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_SHORT_5_5_5_1; break; case SDL_PIXELFORMAT_RGBA4444: internalFormat = GL_RGBA; format = GL_RGBA; type = GL_UNSIGNED_SHORT_4_4_4_4; break; default: SDL_SetError("Texture format %s not supported by OpenGL ES", SDL_GetPixelFormatName(texture->format)); return -1; } data = (GLES_TextureData *) SDL_calloc(1, sizeof(*data)); if (!data) { SDL_OutOfMemory(); return -1; } if (texture->access == SDL_TEXTUREACCESS_STREAMING) { data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); data->pixels = SDL_malloc(texture->h * data->pitch); if (!data->pixels) { SDL_OutOfMemory(); SDL_free(data); return -1; } } texture->driverdata = data; renderdata->glGetError(); renderdata->glEnable(GL_TEXTURE_2D); renderdata->glGenTextures(1, &data->texture); data->type = GL_TEXTURE_2D; /* no NPOV textures allowed in OpenGL ES (yet) */ texture_w = power_of_2(texture->w); texture_h = power_of_2(texture->h); data->texw = (GLfloat) texture->w / texture_w; data->texh = (GLfloat) texture->h / texture_h; if( renderer->info.max_texture_width < texture_w || renderer->info.max_texture_height < texture_h ) __android_log_print(ANDROID_LOG_WARN, "libSDL", "GLES: Allocated texture of size %dx%d which is bigger than largest possible device texture %dx%d", texture_w, texture_h, renderer->info.max_texture_width, renderer->info.max_texture_height ); else if( texture_w > 1024 || texture_h > 1024 ) __android_log_print(ANDROID_LOG_WARN, "libSDL", "GLES: Allocated texture of size %dx%d which is bigger than 1024x1024 - this code will not work on HTC G1", texture_w, texture_h ); data->format = format; data->formattype = type; renderdata->glBindTexture(data->type, data->texture); renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, GL_NEAREST); renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, GL_NEAREST); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0, format, type, NULL); renderdata->glDisable(GL_TEXTURE_2D); result = renderdata->glGetError(); if (result != GL_NO_ERROR) { GLES_SetError("glTexImage2D()", result); return -1; } return 0; }
SDL_bool SDLTest_CommonInit(SDLTest_CommonState * state) { int i, j, m, n, w, h; SDL_DisplayMode fullscreen_mode; if (state->flags & SDL_INIT_VIDEO) { if (state->verbose & VERBOSE_VIDEO) { n = SDL_GetNumVideoDrivers(); if (n == 0) { fprintf(stderr, "No built-in video drivers\n"); } else { fprintf(stderr, "Built-in video drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { fprintf(stderr, ","); } fprintf(stderr, " %s", SDL_GetVideoDriver(i)); } fprintf(stderr, "\n"); } } if (SDL_VideoInit(state->videodriver) < 0) { fprintf(stderr, "Couldn't initialize video driver: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->verbose & VERBOSE_VIDEO) { fprintf(stderr, "Video driver: %s\n", SDL_GetCurrentVideoDriver()); } /* Upload GL settings */ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, state->gl_red_size); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, state->gl_green_size); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, state->gl_blue_size); SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, state->gl_alpha_size); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, state->gl_double_buffer); SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, state->gl_buffer_size); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, state->gl_depth_size); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, state->gl_stencil_size); SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, state->gl_accum_red_size); SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, state->gl_accum_green_size); SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, state->gl_accum_blue_size); SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, state->gl_accum_alpha_size); SDL_GL_SetAttribute(SDL_GL_STEREO, state->gl_stereo); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, state->gl_multisamplebuffers); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, state->gl_multisamplesamples); if (state->gl_accelerated >= 0) { SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, state->gl_accelerated); } SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, state->gl_retained_backing); if (state->gl_major_version) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, state->gl_major_version); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, state->gl_minor_version); } if (state->gl_debug) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); } if (state->verbose & VERBOSE_MODES) { SDL_Rect bounds; SDL_DisplayMode mode; int bpp; Uint32 Rmask, Gmask, Bmask, Amask; n = SDL_GetNumVideoDisplays(); fprintf(stderr, "Number of displays: %d\n", n); for (i = 0; i < n; ++i) { fprintf(stderr, "Display %d: %s\n", i, SDL_GetDisplayName(i)); SDL_zero(bounds); SDL_GetDisplayBounds(i, &bounds); fprintf(stderr, "Bounds: %dx%d at %d,%d\n", bounds.w, bounds.h, bounds.x, bounds.y); SDL_GetDesktopDisplayMode(i, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); fprintf(stderr, " Current mode: %dx%d@%dHz, %d bits-per-pixel (%s)\n", mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { fprintf(stderr, " Red Mask = 0x%.8x\n", Rmask); fprintf(stderr, " Green Mask = 0x%.8x\n", Gmask); fprintf(stderr, " Blue Mask = 0x%.8x\n", Bmask); if (Amask) fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask); } /* Print available fullscreen video modes */ m = SDL_GetNumDisplayModes(i); if (m == 0) { fprintf(stderr, "No available fullscreen video modes\n"); } else { fprintf(stderr, " Fullscreen video modes:\n"); for (j = 0; j < m; ++j) { SDL_GetDisplayMode(i, j, &mode); SDL_PixelFormatEnumToMasks(mode.format, &bpp, &Rmask, &Gmask, &Bmask, &Amask); fprintf(stderr, " Mode %d: %dx%d@%dHz, %d bits-per-pixel (%s)\n", j, mode.w, mode.h, mode.refresh_rate, bpp, SDL_GetPixelFormatName(mode.format)); if (Rmask || Gmask || Bmask) { fprintf(stderr, " Red Mask = 0x%.8x\n", Rmask); fprintf(stderr, " Green Mask = 0x%.8x\n", Gmask); fprintf(stderr, " Blue Mask = 0x%.8x\n", Bmask); if (Amask) fprintf(stderr, " Alpha Mask = 0x%.8x\n", Amask); } } } } } if (state->verbose & VERBOSE_RENDER) { SDL_RendererInfo info; n = SDL_GetNumRenderDrivers(); if (n == 0) { fprintf(stderr, "No built-in render drivers\n"); } else { fprintf(stderr, "Built-in render drivers:\n"); for (i = 0; i < n; ++i) { SDL_GetRenderDriverInfo(i, &info); SDLTest_PrintRenderer(&info); } } } SDL_zero(fullscreen_mode); switch (state->depth) { case 8: fullscreen_mode.format = SDL_PIXELFORMAT_INDEX8; break; case 15: fullscreen_mode.format = SDL_PIXELFORMAT_RGB555; break; case 16: fullscreen_mode.format = SDL_PIXELFORMAT_RGB565; break; case 24: fullscreen_mode.format = SDL_PIXELFORMAT_RGB24; break; default: fullscreen_mode.format = SDL_PIXELFORMAT_RGB888; break; } fullscreen_mode.refresh_rate = state->refresh_rate; state->windows = (SDL_Window **) SDL_malloc(state->num_windows * sizeof(*state->windows)); state->renderers = (SDL_Renderer **) SDL_malloc(state->num_windows * sizeof(*state->renderers)); if (!state->windows || !state->renderers) { fprintf(stderr, "Out of memory!\n"); return SDL_FALSE; } for (i = 0; i < state->num_windows; ++i) { char title[1024]; if (state->num_windows > 1) { SDL_snprintf(title, SDL_arraysize(title), "%s %d", state->window_title, i + 1); } else { SDL_strlcpy(title, state->window_title, SDL_arraysize(title)); } state->windows[i] = SDL_CreateWindow(title, state->window_x, state->window_y, state->window_w, state->window_h, state->window_flags); if (!state->windows[i]) { fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->window_minW || state->window_minH) { SDL_SetWindowMinimumSize(state->windows[i], state->window_minW, state->window_minH); } if (state->window_maxW || state->window_maxH) { SDL_SetWindowMaximumSize(state->windows[i], state->window_maxW, state->window_maxH); } SDL_GetWindowSize(state->windows[i], &w, &h); if (!(state->window_flags & SDL_WINDOW_RESIZABLE) && (w != state->window_w || h != state->window_h)) { printf("Window requested size %dx%d, got %dx%d\n", state->window_w, state->window_h, w, h); state->window_w = w; state->window_h = h; } if (SDL_SetWindowDisplayMode(state->windows[i], &fullscreen_mode) < 0) { fprintf(stderr, "Can't set up fullscreen display mode: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->window_icon) { SDL_Surface *icon = SDLTest_LoadIcon(state->window_icon); if (icon) { SDL_SetWindowIcon(state->windows[i], icon); SDL_FreeSurface(icon); } } SDL_ShowWindow(state->windows[i]); state->renderers[i] = NULL; if (!state->skip_renderer && (state->renderdriver || !(state->window_flags & SDL_WINDOW_OPENGL))) { m = -1; if (state->renderdriver) { SDL_RendererInfo info; n = SDL_GetNumRenderDrivers(); for (j = 0; j < n; ++j) { SDL_GetRenderDriverInfo(j, &info); if (SDL_strcasecmp(info.name, state->renderdriver) == 0) { m = j; break; } } if (m == n) { fprintf(stderr, "Couldn't find render driver named %s", state->renderdriver); return SDL_FALSE; } } state->renderers[i] = SDL_CreateRenderer(state->windows[i], m, state->render_flags); if (!state->renderers[i]) { fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->logical_w && state->logical_h) { SDL_RenderSetLogicalSize(state->renderers[i], state->logical_w, state->logical_h); } else if (state->scale) { SDL_RenderSetScale(state->renderers[i], state->scale, state->scale); } if (state->verbose & VERBOSE_RENDER) { SDL_RendererInfo info; fprintf(stderr, "Current renderer:\n"); SDL_GetRendererInfo(state->renderers[i], &info); SDLTest_PrintRenderer(&info); } } } } if (state->flags & SDL_INIT_AUDIO) { if (state->verbose & VERBOSE_AUDIO) { n = SDL_GetNumAudioDrivers(); if (n == 0) { fprintf(stderr, "No built-in audio drivers\n"); } else { fprintf(stderr, "Built-in audio drivers:"); for (i = 0; i < n; ++i) { if (i > 0) { fprintf(stderr, ","); } fprintf(stderr, " %s", SDL_GetAudioDriver(i)); } fprintf(stderr, "\n"); } } if (SDL_AudioInit(state->audiodriver) < 0) { fprintf(stderr, "Couldn't initialize audio driver: %s\n", SDL_GetError()); return SDL_FALSE; } if (state->verbose & VERBOSE_VIDEO) { fprintf(stderr, "Audio driver: %s\n", SDL_GetCurrentAudioDriver()); } if (SDL_OpenAudio(&state->audiospec, NULL) < 0) { fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError()); return SDL_FALSE; } } return SDL_TRUE; }
SDLWindowManager::SDLWindowManager(Application* application): WindowManager(application) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == -1) { throw RuntimeException("SDL initialization failed."); } int displayCount = SDL_GetNumVideoDisplays(); displays.resize(displayCount); primaryDisplay = &displays[0]; for (int i = 0; i < displayCount; ++i) { Display* display = &displays[i]; const char* displayName = SDL_GetDisplayName(i); if (displayName) { display->setName(displayName); } SDL_DisplayMode sdlCurrentDisplayMode; SDL_GetCurrentDisplayMode(i, &sdlCurrentDisplayMode); int displayModeCount = SDL_GetNumDisplayModes(i); for (int j = 0; j < displayModeCount; ++j) { SDL_DisplayMode sdlDisplayMode; SDL_GetDisplayMode(i, j, &sdlDisplayMode); SDL_PixelFormat* format = SDL_AllocFormat(sdlDisplayMode.format); if (!format) { std::cerr << "Failed to create SDL pixel format: " << SDL_GetPixelFormatName(sdlDisplayMode.format) << '\n'; continue; } int width = sdlDisplayMode.w; int height = sdlDisplayMode.h; int refreshRate = sdlDisplayMode.refresh_rate; int redBits, greenBits, blueBits, alphaBits; SDLPixelFormatMap::getChannelBits(format, &redBits, &greenBits, &blueBits, &alphaBits); SDL_FreeFormat(format); display->addMode( DisplayMode(width, height, redBits, greenBits, blueBits, alphaBits, refreshRate)); if (sdlCurrentDisplayMode.w == sdlDisplayMode.w && sdlCurrentDisplayMode.h == sdlDisplayMode.h && sdlCurrentDisplayMode.format == sdlDisplayMode.format && sdlCurrentDisplayMode.refresh_rate == sdlDisplayMode.refresh_rate) { display->setCurrentMode(j); } } } keyboard = new Keyboard("Default Keyboard"); mouse = new Mouse("Default Mouse"); application->getInputManager()->registerKeyboard(keyboard); application->getInputManager()->registerMouse(mouse); }
int inline PixelFormat::getName(State & state, SDL_PixelFormat * format) { Stack * stack = state.stack; stack->push<const std::string &>(SDL_GetPixelFormatName(format->format)); return 1; }
Texture::Texture(SDL_Surface &surface, GLenum texUnit) { GLint intFormat; GLenum format, type; bool recognised; _refCount = 0; glGenTextures(1, &_GLtexture); Logger::logprintf(Logger::LOG_VERBOSEINFO, Logger::LOG_TEXTURES, "Loading SDL Surface 0x%X (Pixel Format %s) to OpenGL name %i and Texture Unit GL_TEXTURE%i\n", &surface,SDL_GetPixelFormatName(surface.format->format), _GLtexture, texUnit - GL_TEXTURE0); switch(surface.format->format) { case SDL_PIXELFORMAT_ABGR8888: intFormat = GL_RGBA8; format = GL_RGBA; type = GL_UNSIGNED_BYTE; recognised = true; break; case SDL_PIXELFORMAT_ARGB8888: intFormat = GL_RGBA8; format = GL_BGRA; type = GL_UNSIGNED_BYTE; recognised = true; break; default: Logger::logprintf(Logger::LOG_WARN, Logger::LOG_TEXTURES, "No mapped GL format for SDL pixel format %s, will be reformatted internally\n", SDL_GetPixelFormatName(surface.format->format)); recognised = false; break; } glActiveTexture(texUnit); glBindTexture( GL_TEXTURE_2D, _GLtexture); _loaded = checkGLError("glBindTexture failed: %s\n", Logger::LOG_ERROR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); if ( recognised ) { glTexImage2D( GL_TEXTURE_2D, 0, intFormat, surface.w, surface.h , 0, format, type, surface.pixels ); } else { SDL_Surface *surface_bgra; Logger::logprintf(Logger::LOG_INFO, Logger::LOG_TEXTURES, "Converting source SDL pixel format %s to SDL_PIXELFORMAT_ABGR8888\n", SDL_GetPixelFormatName(surface.format->format)); surface_bgra = SDL_ConvertSurfaceFormat(&surface, SDL_PIXELFORMAT_ABGR8888, 0); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface_bgra->w, surface_bgra->h , 0, GL_RGBA, GL_UNSIGNED_BYTE, surface_bgra->pixels ); SDL_FreeSurface(surface_bgra); } _loaded &= checkGLError("Failed to load texture from SDL Surface: %s\n", Logger::LOG_ERROR); }
static int GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) { GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; GL_TextureData *data; GLint internalFormat; GLenum format, type; int texture_w, texture_h; GLenum result; GL_ActivateRenderer(renderer); if (!convert_format(renderdata, texture->format, &internalFormat, &format, &type)) { SDL_SetError("Texture format %s not supported by OpenGL", SDL_GetPixelFormatName(texture->format)); return -1; } data = (GL_TextureData *) SDL_calloc(1, sizeof(*data)); if (!data) { SDL_OutOfMemory(); return -1; } if (texture->access == SDL_TEXTUREACCESS_STREAMING) { size_t size; data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); size = texture->h * data->pitch; if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { /* Need to add size for the U and V planes */ size += (2 * (texture->h * data->pitch) / 4); } data->pixels = SDL_malloc(size); if (!data->pixels) { SDL_OutOfMemory(); SDL_free(data); return -1; } } texture->driverdata = data; renderdata->glGetError(); renderdata->glGenTextures(1, &data->texture); if (renderdata->GL_ARB_texture_rectangle_supported) { data->type = GL_TEXTURE_RECTANGLE_ARB; texture_w = texture->w; texture_h = texture->h; data->texw = (GLfloat) texture_w; data->texh = (GLfloat) texture_h; } else { data->type = GL_TEXTURE_2D; texture_w = power_of_2(texture->w); texture_h = power_of_2(texture->h); data->texw = (GLfloat) (texture->w) / texture_w; data->texh = (GLfloat) texture->h / texture_h; } data->format = format; data->formattype = type; data->scaleMode = GL_LINEAR; renderdata->glEnable(data->type); renderdata->glBindTexture(data->type, data->texture); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); #ifdef __MACOSX__ #ifndef GL_TEXTURE_STORAGE_HINT_APPLE #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC #endif #ifndef STORAGE_CACHED_APPLE #define STORAGE_CACHED_APPLE 0x85BE #endif #ifndef STORAGE_SHARED_APPLE #define STORAGE_SHARED_APPLE 0x85BF #endif if (texture->access == SDL_TEXTUREACCESS_STREAMING) { renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE); } else { renderdata->glTexParameteri(data->type, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE); } if (texture->access == SDL_TEXTUREACCESS_STREAMING && texture->format == SDL_PIXELFORMAT_ARGB8888) { renderdata->glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0, format, type, data->pixels); } else #endif { renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w, texture_h, 0, format, type, NULL); } renderdata->glDisable(data->type); result = renderdata->glGetError(); if (result != GL_NO_ERROR) { GL_SetError("glTexImage2D()", result); return -1; } if (texture->format == SDL_PIXELFORMAT_YV12 || texture->format == SDL_PIXELFORMAT_IYUV) { data->yuv = SDL_TRUE; renderdata->glGenTextures(1, &data->utexture); renderdata->glGenTextures(1, &data->vtexture); renderdata->glEnable(data->type); renderdata->glBindTexture(data->type, data->utexture); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2, texture_h/2, 0, format, type, NULL); renderdata->glBindTexture(data->type, data->vtexture); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w/2, texture_h/2, 0, format, type, NULL); renderdata->glDisable(data->type); } return 0; }
/** * @brief Init the SDL window */ bool R_InitGraphics (const viddefContext_t* context) { uint32_t flags; int i; SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if (context->multisample > 0) { Com_Printf("I: set multisample buffers to %i\n", context->multisample); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, context->multisample); } else { Com_Printf("I: disable multisample buffers\n"); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0); } #if SDL_VERSION_ATLEAST(2,0,0) /* valid values are between -1 and 1 */ i = std::min(1, std::max(-1, context->swapinterval)); Com_Printf("I: set swap control to %i\n", i); SDL_GL_SetSwapInterval(i); flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN; if (context->fullscreen) flags |= SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS; const int videoDrivers = SDL_GetNumVideoDrivers(); for (int i = 0; i < videoDrivers; ++i) { Com_Printf("available driver: %s\n", SDL_GetVideoDriver(i)); } SDL_DisplayMode displayMode; SDL_GetDesktopDisplayMode(0, &displayMode); const char* name = SDL_GetPixelFormatName(displayMode.format); Com_Printf("current desktop mode: %dx%d@%dHz (%s)\n", displayMode.w, displayMode.h, displayMode.refresh_rate, name); SDL_VideoInit(nullptr); SDL_SetModState(KMOD_NONE); SDL_StopTextInput(); Com_Printf("driver: %s\n", SDL_GetCurrentVideoDriver()); const int displays = SDL_GetNumVideoDisplays(); Com_Printf("found %i display(s)\n", displays); int width = context->width; int height = context->height; if (context->fullscreen && displays > 1) { width = displayMode.w; height = displayMode.h; Com_Printf("use fake fullscreen for the first display: %i:%i\n", width, height); } cls.window = SDL_CreateWindow(GAME_TITLE_LONG, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, flags); if (!cls.window) { const char* error = SDL_GetError(); Com_Printf("SDL SDL_CreateWindow failed: %s\n", error); SDL_ClearError(); return -1; } cls.context = SDL_GL_CreateContext(cls.window); #else /* valid values are between 0 and 2 */ i = std::min(2, std::max(0, context->swapinterval)); Com_Printf("I: set swap control to %i\n", i); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, i); flags = SDL_OPENGL; if (context->fullscreen) flags |= SDL_FULLSCREEN; /*flags |= SDL_NOFRAME;*/ SDL_Surface* screen = SDL_SetVideoMode(context->width, context->height, 0, flags); if (!screen) { const char* error = SDL_GetError(); Com_Printf("SDL SetVideoMode failed: %s\n", error); SDL_ClearError(); return false; } #endif SDL_ShowCursor(SDL_DISABLE); return true; }
extern SkinSurface* skin_surface_create_window(int x, int y, int w, int h, int original_w, int original_h, int is_fullscreen) { static SkinSurface* result = NULL; SDL_Window* window = skin_winsys_get_window(); SDL_Renderer* renderer = globals_get_renderer(); D("%s: x=%d y=%d w=%d h=%d original_w=%d original_h=%d is_fullscreen=%d", __FUNCTION__, x, y, w, h, original_w, original_h, is_fullscreen); // Textures do not survive window resize events, so globals_foreach_surface(&_skin_surface_destroy_texture, NULL); if (!window) { // NOTE: Don't use SDL_WINDOW_ALLOW_HIGHDPI here. On OS X, this will // make mouse event coordinates twice smaller than needed // when running on a high-dpi machine (e.g. recent MacBook Pro), // making the UI unusable. Note that this doesn't happen on a // 'low-dpi' device such as a MacPro connected to a 30" monitor. int window_flags = SDL_WINDOW_OPENGL; if (is_fullscreen) { window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } window = SDL_CreateWindow("Android emulator", x, y, w, h, window_flags); if (!window) { panic("Could not create SDL2 window: %s\n", SDL_GetError()); } skin_winsys_set_window(window); } else { if (is_fullscreen) { SDL_CHECK(SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP)); #if DEBUG #endif } else { SDL_CHECK(SDL_SetWindowFullscreen(window, 0)); SDL_SetWindowPosition(window, x, y); SDL_SetWindowSize(window, w, h); } } // Generate renderer if (!renderer) { SDL_CHECK(SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear")); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED| SDL_RENDERER_PRESENTVSYNC| SDL_RENDERER_TARGETTEXTURE); if (!renderer) { panic("Could not create renderer: %s\n", SDL_GetError()); } globals_set_renderer(renderer); } SDL_CHECK(SDL_RenderSetLogicalSize(renderer, original_w, original_h)); if (DEBUG && VERBOSE_CHECK(surface)) { SDL_RendererInfo info; SDL_CHECK(SDL_GetRendererInfo(renderer, &info)); printf("renderer.name = %s\n", info.name); printf("renderer.flags = 0x%x\n", info.flags); printf("renderer.num_texture_formats = %d\n", info.num_texture_formats); int nn; for (nn = 0; nn < info.num_texture_formats; ++nn) { printf(" 0x%x (%s)\n", info.texture_formats[nn], SDL_GetPixelFormatName(info.texture_formats[nn])); } printf("renderer.max_texture_width = %d\n", info.max_texture_width); printf("renderer.max_texture_height = %d\n", info.max_texture_height); } // Compute scaling parameters. { int window_x, window_y, window_w, window_h; SDL_GetWindowSize(window, &window_w, &window_h); SDL_GetWindowPosition(window, &window_x, &window_y); D("Window pos=(%d,%d) size=(%d,%d)", window_x, window_y, window_w, window_h); double x_scale = window_w * 1.0 / original_w; double y_scale = window_h * 1.0 / original_h; double scale = (x_scale <= y_scale) ? x_scale : y_scale; double effective_x = 0.; double effective_y = 0.; if (is_fullscreen) { effective_x = (window_w - original_w * scale) * 0.5; effective_y = (window_h - original_h * scale) * 0.5; } globals_set_window_scale(scale, effective_x, effective_y); } SDL_Texture* texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, original_w, original_h); if (!texture) { panic("Could not create window texture: %s", SDL_GetError()); } SDL_CHECK(SDL_SetRenderTarget(renderer, texture)); SDL_CHECK(SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255)); SDL_CHECK(SDL_RenderClear(renderer)); SDL_CHECK(SDL_SetRenderTarget(renderer, NULL)); SDL_CHECK(SDL_SetRenderDrawColor(renderer, 0, 0, 128, 255)); SDL_CHECK(SDL_RenderClear(renderer)); SDL_CHECK(SDL_RenderCopy(renderer, texture, NULL, NULL)); SDL_RenderPresent(renderer); if (!result) { result = _skin_surface_create(NULL, texture, original_w, original_h); } else { result->texture = texture; result->w = original_w; result->h = original_h; } skin_surface_ref(result); // Ensure all textures are regenerated properly. globals_foreach_surface(&_skin_surface_reset_texture, renderer); return result; }
void init_sdl() { SDL_version sdl_compiled_version, sdl_linked_version; SDL_VERSION(&sdl_compiled_version); SDL_GetVersion(&sdl_linked_version); printf("Using SDL backend. Compiled against SDL %d.%d.%d, linked to SDL %d.%d.%d.\n", sdl_compiled_version.major, sdl_compiled_version.minor, sdl_compiled_version.patch, sdl_linked_version.major, sdl_linked_version.minor, sdl_linked_version.patch); // SDL and video // Make this configurable later SDL_DisableScreenSaver(); fail_if(SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) != 0, "failed to initialize SDL: %s", SDL_GetError()); fail_if(!(screen = SDL_CreateWindow( "Nesalizer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_RESIZABLE)), "failed to create window: %s", SDL_GetError()); fail_if(!(renderer = SDL_CreateRenderer(screen, -1, 0)), "failed to create rendering context: %s", SDL_GetError()); SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); // Display some information about the renderer SDL_RendererInfo renderer_info; if (SDL_GetRendererInfo(renderer, &renderer_info)) puts("Failed to get renderer information from SDL"); else { if (renderer_info.name) printf("renderer: uses renderer \"%s\"\n", renderer_info.name); if (renderer_info.flags & SDL_RENDERER_SOFTWARE) puts("renderer: uses software rendering"); if (renderer_info.flags & SDL_RENDERER_ACCELERATED) puts("renderer: uses hardware-accelerated rendering"); if (renderer_info.flags & SDL_RENDERER_PRESENTVSYNC) puts("renderer: uses vsync"); if (renderer_info.flags & SDL_RENDERER_TARGETTEXTURE) puts("renderer: supports rendering to texture"); printf("renderer: available texture formats:"); unsigned const n_texture_formats = min(16u, (unsigned)renderer_info.num_texture_formats); for (unsigned i = 0; i < n_texture_formats; ++i) printf(" %s", SDL_GetPixelFormatName(renderer_info.texture_formats[i])); putchar('\n'); } fail_if(!(screen_tex = SDL_CreateTexture( renderer, // SDL takes endianess into account, so this becomes GL_RGBA8 // internally on little-endian systems SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, 256, 240)), "failed to create texture for screen: %s", SDL_GetError()); static Uint32 render_buffers[2][240*256]; back_buffer = render_buffers[0]; front_buffer = render_buffers[1]; // Audio SDL_AudioSpec want; SDL_zero(want); want.freq = sample_rate; want.format = AUDIO_S16SYS; want.channels = 1; want.samples = sdl_audio_buffer_size; want.callback = audio_callback; fail_if(!(audio_device_id = SDL_OpenAudioDevice(0, 0, &want, 0, 0)), "failed to initialize audio: %s\n", SDL_GetError()); // Input // We use SDL_GetKey/MouseState() instead SDL_EventState(SDL_KEYDOWN , SDL_IGNORE); SDL_EventState(SDL_KEYUP , SDL_IGNORE); SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE); SDL_EventState(SDL_MOUSEBUTTONUP , SDL_IGNORE); SDL_EventState(SDL_KEYUP , SDL_IGNORE); SDL_EventState(SDL_MOUSEMOTION , SDL_IGNORE); // Ignore window events for now //SDL_EventState(SDL_WINDOWEVENT, SDL_IGNORE); keys = SDL_GetKeyboardState(0); // SDL thread synchronization fail_if(!(event_lock = SDL_CreateMutex()), "failed to create event mutex: %s", SDL_GetError()); fail_if(!(frame_lock = SDL_CreateMutex()), "failed to create frame mutex: %s", SDL_GetError()); fail_if(!(frame_available_cond = SDL_CreateCond()), "failed to create frame condition variable: %s", SDL_GetError()); }
SDLRenderer::SDLRenderer() : m_window(), m_renderer(), m_viewport(), m_desktop_size(0, 0), m_scale(1.0f, 1.0f) { SDL_DisplayMode mode; if (SDL_GetDesktopDisplayMode(0, &mode) != 0) { log_warning << "Couldn't get desktop display mode: " << SDL_GetError() << std::endl; } else { m_desktop_size = Size(mode.w, mode.h); } log_info << "creating SDLRenderer" << std::endl; int width = g_config->window_size.width; int height = g_config->window_size.height; int flags = SDL_WINDOW_RESIZABLE; if(g_config->use_fullscreen) { if (g_config->fullscreen_size == Size(0, 0)) { flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; width = g_config->window_size.width; height = g_config->window_size.height; } else { flags |= SDL_WINDOW_FULLSCREEN; width = g_config->fullscreen_size.width; height = g_config->fullscreen_size.height; } } SCREEN_WIDTH = width; SCREEN_HEIGHT = height; m_viewport.x = 0; m_viewport.y = 0; m_viewport.w = width; m_viewport.h = height; SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); int ret = SDL_CreateWindowAndRenderer(width, height, flags, &m_window, &m_renderer); if(ret != 0) { std::stringstream msg; msg << "Couldn't set video mode (" << width << "x" << height << "): " << SDL_GetError(); throw std::runtime_error(msg.str()); } SDL_RendererInfo info; if (SDL_GetRendererInfo(m_renderer, &info) != 0) { log_warning << "Couldn't get RendererInfo: " << SDL_GetError() << std::endl; } else { log_info << "SDL_Renderer: " << info.name << std::endl; log_info << "SDL_RendererFlags: " << std::endl; if (info.flags & SDL_RENDERER_SOFTWARE) { log_info << " SDL_RENDERER_SOFTWARE" << std::endl; } if (info.flags & SDL_RENDERER_ACCELERATED) { log_info << " SDL_RENDERER_ACCELERATED" << std::endl; } if (info.flags & SDL_RENDERER_PRESENTVSYNC) { log_info << " SDL_RENDERER_PRESENTVSYNC" << std::endl; } if (info.flags & SDL_RENDERER_TARGETTEXTURE) { log_info << " SDL_RENDERER_TARGETTEXTURE" << std::endl; } log_info << "Texture Formats: " << std::endl; for(size_t i = 0; i < info.num_texture_formats; ++i) { log_info << " " << SDL_GetPixelFormatName(info.texture_formats[i]) << std::endl; } log_info << "Max Texture Width: " << info.max_texture_width << std::endl; log_info << "Max Texture Height: " << info.max_texture_height << std::endl; } g_config->window_size = Size(width, height); apply_config(); }