diff options
Diffstat (limited to 'backends')
| -rw-r--r-- | backends/graphics/opengl/gltexture.cpp | 43 | ||||
| -rw-r--r-- | backends/graphics/opengl/gltexture.h | 9 | ||||
| -rw-r--r-- | backends/graphics/opengl/opengl-graphics.cpp | 39 | ||||
| -rw-r--r-- | backends/graphics/opengl/opengl-graphics.h | 2 | ||||
| -rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.cpp | 39 | ||||
| -rw-r--r-- | backends/graphics/openglsdl/openglsdl-graphics.h | 1 | 
6 files changed, 75 insertions, 58 deletions
diff --git a/backends/graphics/opengl/gltexture.cpp b/backends/graphics/opengl/gltexture.cpp index e1fb5ba00d..e3760ee2d8 100644 --- a/backends/graphics/opengl/gltexture.cpp +++ b/backends/graphics/opengl/gltexture.cpp @@ -77,7 +77,10 @@ GLTexture::GLTexture(byte bpp, GLenum format, GLenum type)  	_glFormat(format),  	_glType(type),  	_textureWidth(0), -	_textureHeight(0) { +	_textureHeight(0), +	_realWidth(0), +	_realHeight(0), +	_refresh(false) {  	// Generates the texture ID for GL  	CHECK_GL_ERROR( glGenTextures(1, &_textureName) ); @@ -91,22 +94,20 @@ GLTexture::GLTexture(byte bpp, GLenum format, GLenum type)  }  GLTexture::~GLTexture() { -	debug("Destroying texture %u", _textureName);  	CHECK_GL_ERROR( glDeleteTextures(1, &_textureName) );  }  void GLTexture::refresh() {  	// Generates the texture ID for GL -	//CHECK_GL_ERROR( glGenTextures(1, &_textureName) ); -	//updateBuffer(_surface.pixels, _surface.bytesPerPixel, 0, 0, _surface.w, _surface.h); +	CHECK_GL_ERROR( glGenTextures(1, &_textureName) ); +	_refresh = true;  }  void GLTexture::allocBuffer(GLuint w, GLuint h) { -	_surface.w = w; -	_surface.h = h; -	_surface.bytesPerPixel = _bytesPerPixel; - -	if (w <= _textureWidth && h <= _textureHeight) +	_realWidth = w; +	_realHeight = h; +	 +	if (w <= _textureWidth && h <= _textureHeight && !_refresh)  		// Already allocated a sufficiently large buffer  		return; @@ -117,9 +118,6 @@ void GLTexture::allocBuffer(GLuint w, GLuint h) {  		_textureWidth = nextHigher2(w);  		_textureHeight = nextHigher2(h);  	} -	_surface.pitch = _textureWidth * _bytesPerPixel; - -	//_surface.create(w, h, _bytesPerPixel);  	// Allocate room for the texture now, but pixel data gets uploaded  	// later (perhaps with multiple TexSubImage2D operations). @@ -130,6 +128,11 @@ void GLTexture::allocBuffer(GLuint w, GLuint h) {  	CHECK_GL_ERROR( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );  	CHECK_GL_ERROR( glTexImage2D(GL_TEXTURE_2D, 0, _glFormat,  		     _textureWidth, _textureHeight, 0, _glFormat, _glType, NULL) ); + +	if (_surface.w != _textureWidth || _surface.h != _textureHeight) +		_surface.create(_textureWidth, _textureHeight, _bytesPerPixel); + +	_refresh = false;  }  void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLuint w, GLuint h) { @@ -138,15 +141,13 @@ void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLu  	if (static_cast<int>(w) * _bytesPerPixel == pitch) {  		CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h,  						_glFormat, _glType, buf) ); -		//memcpy(_surface.pixels, buf, w * pitch); +		memcpy(_surface.getBasePtr(x, y), buf, h * pitch);  	} else { -		// GLES removed the ability to specify pitch, so we -		// have to do this row by row.  		const byte* src = static_cast<const byte*>(buf);  		do {  			CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, x, y,  							w, 1, _glFormat, _glType, src) ); -			//memcpy(_surface.pixels, src, pitch); +			memcpy(_surface.getBasePtr(x, y), src, w * _bytesPerPixel);  			++y;  			src += pitch;  		} while (--h); @@ -154,19 +155,17 @@ void GLTexture::updateBuffer(const void *buf, int pitch, GLuint x, GLuint y, GLu  }  void GLTexture::fillBuffer(byte x) { -	byte* tmpbuf = new byte[_surface.h * _surface.w * _bytesPerPixel]; -	memset(tmpbuf, x, _surface.h * _surface.w * _bytesPerPixel); +	memset(_surface.pixels, x, _surface.h * _surface.pitch);  	CHECK_GL_ERROR( glBindTexture(GL_TEXTURE_2D, _textureName) );  	CHECK_GL_ERROR( glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _surface.w, _surface.h, -					_glFormat, _glType, tmpbuf) ); -	delete[] tmpbuf; +		_glFormat, _glType, _surface.pixels) );  }  void GLTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {  	CHECK_GL_ERROR( glBindTexture(GL_TEXTURE_2D, _textureName) ); -	const GLfloat texWidth = (GLfloat)_surface.w / _textureWidth;//xdiv(_surface.w, _textureWidth); -	const GLfloat texHeight = (GLfloat)_surface.h / _textureHeight;//xdiv(_surface.h, _textureHeight); +	const GLfloat texWidth = (GLfloat)_realWidth / _textureWidth;//xdiv(_surface.w, _textureWidth); +	const GLfloat texHeight = (GLfloat)_realHeight / _textureHeight;//xdiv(_surface.h, _textureHeight);  	const GLfloat texcoords[] = {  		0, 0,  		texWidth, 0, diff --git a/backends/graphics/opengl/gltexture.h b/backends/graphics/opengl/gltexture.h index 88a2b59962..d689e02951 100644 --- a/backends/graphics/opengl/gltexture.h +++ b/backends/graphics/opengl/gltexture.h @@ -65,13 +65,13 @@ public:  	virtual void updateBuffer(const void *buf, int pitch, GLuint x, GLuint y,  		GLuint w, GLuint h); -	virtual void drawTexture() { drawTexture(0, 0, _surface.w, _surface.h); } +	virtual void drawTexture() { drawTexture(0, 0, _realWidth, _realHeight); }  	virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h);  	Graphics::Surface *getSurface() { return &_surface; } -	GLuint getWidth() const { return _surface.w; } -	GLuint getHeight() const { return _surface.h; } +	GLuint getWidth() const { return _realWidth; } +	GLuint getHeight() const { return _realHeight; }  	GLuint getTextureName() const { return _textureName; }  protected: @@ -80,7 +80,10 @@ protected:  	const GLenum _glType;  	Graphics::Surface _surface; +	GLuint _realWidth; +	GLuint _realHeight;  	GLuint _textureName;  	GLuint _textureWidth;  	GLuint _textureHeight; +	bool _refresh;  }; diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index 413f4221f1..540e1ada0e 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -226,9 +226,9 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {  	}  #ifdef USE_RGB_COLOR -	if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged) { +	if (_transactionDetails.sizeChanged || _transactionDetails.formatChanged || _transactionDetails.needHotswap) {  #else -	if (_transactionDetails.sizeChanged) { +	if (_transactionDetails.sizeChanged || _transactionDetails.needHotswap) {  #endif  		unloadGFXMode();  		if (!loadGFXMode()) { @@ -243,20 +243,6 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {  			_videoMode.setup = true;  			_screenChangeCount++;  		} -	} else if (_transactionDetails.needHotswap) { -		//setGraphicsModeIntern(); -		if (!hotswapGFXMode()) { -			if (_oldVideoMode.setup) { -				_transactionMode = kTransactionRollback; -				errors |= endGFXTransaction(); -			} -		} else { -			_videoMode.setup = true; -			_screenChangeCount++; - -			if (_transactionDetails.needUpdatescreen) -				internUpdateScreen(); -		}  	} else if (_transactionDetails.needUpdatescreen) {  		//setGraphicsModeIntern();  		internUpdateScreen(); @@ -365,13 +351,16 @@ void OpenGLGraphicsManager::clearOverlay() {  }  void OpenGLGraphicsManager::grabOverlay(OverlayColor *buf, int pitch) { -	const Graphics::Surface* surface = _overlayTexture->getSurface(); +	const Graphics::Surface *surface = _overlayTexture->getSurface();  	assert(surface->bytesPerPixel == sizeof(buf[0])); -	int h = surface->h; +	uint w = _overlayTexture->getWidth(); +	uint h = _overlayTexture->getHeight(); +	const byte *src = (byte *)surface->pixels;  	do { -		//memcpy(buf, surface->pixels, surface->w * sizeof(buf[0])); -		memset(buf, 0, surface->w * sizeof(buf[0])); +		//memset(buf, 0, w * sizeof(buf[0])); +		memcpy(buf, src, w * sizeof(buf[0]));  		buf += pitch; +		src += surface->pitch;  	} while (--h);  } @@ -600,19 +589,19 @@ bool OpenGLGraphicsManager::loadGFXMode() {  		GLenum type;  		getGLPixelFormat(_screenFormat, bpp, format, type);  		_gameTexture = new GLTexture(bpp, format, type); -	} else +	} else if (_transactionDetails.newContext)  		_gameTexture->refresh();  	_overlayFormat = Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0);  	if (!_overlayTexture)  		_overlayTexture = new GLTexture(2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4); -	else +	else if (_transactionDetails.newContext)  		_overlayTexture->refresh();  	if (!_cursorTexture)  		_cursorTexture = new GLTexture(4, GL_RGBA, GL_UNSIGNED_BYTE); -	else +	else if (_transactionDetails.newContext)  		_cursorTexture->refresh();  	_gameTexture->allocBuffer(_videoMode.screenWidth, _videoMode.screenHeight); @@ -628,10 +617,6 @@ void OpenGLGraphicsManager::unloadGFXMode() {  } -bool OpenGLGraphicsManager::hotswapGFXMode() { -	return false; -} -  void OpenGLGraphicsManager::setScale(int newScale) {  	if (newScale == _videoMode.scaleFactor)  		return; diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h index d76e328d07..038f658bb9 100644 --- a/backends/graphics/opengl/opengl-graphics.h +++ b/backends/graphics/opengl/opengl-graphics.h @@ -116,6 +116,7 @@ protected:  		bool sizeChanged;  		bool needHotswap;  		bool needUpdatescreen; +		bool newContext;  #ifdef USE_RGB_COLOR  		bool formatChanged;  #endif @@ -147,7 +148,6 @@ protected:  	virtual void internUpdateScreen();  	virtual bool loadGFXMode();  	virtual void unloadGFXMode(); -	virtual bool hotswapGFXMode();  	virtual void setScale(int newScale); diff --git a/backends/graphics/openglsdl/openglsdl-graphics.cpp b/backends/graphics/openglsdl/openglsdl-graphics.cpp index 1eae7dd9c7..fe3662a520 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.cpp +++ b/backends/graphics/openglsdl/openglsdl-graphics.cpp @@ -139,6 +139,35 @@ bool OpenGLSdlGraphicsManager::loadGFXMode() {  	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);  	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +	if (_videoMode.fullscreen) { +		SDL_Rect const* const*availableModes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_OPENGL); +		const SDL_Rect *bestMode = NULL; +		uint bestMetric = (uint)-1; +		while (const SDL_Rect *mode = *availableModes++) { +			if (mode->w < _videoMode.hardwareWidth) +				continue; +			if (mode->h < _videoMode.hardwareHeight) +				continue; + +			uint metric = mode->w * mode->h - _videoMode.hardwareWidth * _videoMode.hardwareHeight; +			if (metric > bestMetric) +				continue; + +			bestMode = mode; +			bestMetric = metric; +		} + +		if (bestMode) { +			_videoMode.hardwareWidth = bestMode->w; +			_videoMode.hardwareHeight = bestMode->h; +		} else { +			_videoMode.fullscreen = false; +		} +	} + +	if (_oldVideoMode.fullscreen != _videoMode.fullscreen) +		_transactionDetails.newContext = true; +  	_hwscreen = SDL_SetVideoMode(_videoMode.hardwareWidth, _videoMode.hardwareHeight, 32,  		_videoMode.fullscreen ? (SDL_FULLSCREEN | SDL_OPENGL) : (SDL_OPENGL | SDL_RESIZABLE)  	); @@ -164,10 +193,6 @@ void OpenGLSdlGraphicsManager::unloadGFXMode() {  	}  } -bool OpenGLSdlGraphicsManager::hotswapGFXMode() { -	return false; -} -  void OpenGLSdlGraphicsManager::internUpdateScreen() {  	OpenGLGraphicsManager::internUpdateScreen(); @@ -216,7 +241,13 @@ bool OpenGLSdlGraphicsManager::handleScalerHotkeys(Common::KeyCode key) {  }  void OpenGLSdlGraphicsManager::setFullscreenMode(bool enable) { +	if (_oldVideoMode.setup && _oldVideoMode.fullscreen == enable) +		return; +	if (_transactionMode == kTransactionActive) { +		_videoMode.fullscreen = enable; +		_transactionDetails.needHotswap = true; +	}  }  bool OpenGLSdlGraphicsManager::isScalerHotkey(const Common::Event &event) { diff --git a/backends/graphics/openglsdl/openglsdl-graphics.h b/backends/graphics/openglsdl/openglsdl-graphics.h index a9ee200ece..b0bf12cd4d 100644 --- a/backends/graphics/openglsdl/openglsdl-graphics.h +++ b/backends/graphics/openglsdl/openglsdl-graphics.h @@ -55,7 +55,6 @@ protected:  	virtual bool loadGFXMode();  	virtual void unloadGFXMode(); -	virtual bool hotswapGFXMode();  	virtual void setFullscreenMode(bool enable);  | 
