aboutsummaryrefslogtreecommitdiff
path: root/backends/graphics/opengl
diff options
context:
space:
mode:
authorJohannes Schickel2016-01-02 05:54:08 +0100
committerJohannes Schickel2016-03-16 20:29:26 +0100
commitde3846923c9a00ff6a8563e33858e12a72bfebda (patch)
treecad910c6b890ba4dd678a0d69805f34de58abec8 /backends/graphics/opengl
parent8b0cf0c5f7aa34e88a7702c4e9f54f5d8adc5ab8 (diff)
downloadscummvm-rg350-de3846923c9a00ff6a8563e33858e12a72bfebda.tar.gz
scummvm-rg350-de3846923c9a00ff6a8563e33858e12a72bfebda.tar.bz2
scummvm-rg350-de3846923c9a00ff6a8563e33858e12a72bfebda.zip
OPENGL: Introduce simple abstraction for surfaces.
This is basically an interface extracted from Texture without any knowledge about any actual implementation, except for copyRectToTexture, fill, and dirty rect handling. These are convenient helpers.
Diffstat (limited to 'backends/graphics/opengl')
-rw-r--r--backends/graphics/opengl/opengl-graphics.cpp28
-rw-r--r--backends/graphics/opengl/opengl-graphics.h20
-rw-r--r--backends/graphics/opengl/texture.cpp111
-rw-r--r--backends/graphics/opengl/texture.h116
4 files changed, 168 insertions, 107 deletions
diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp
index 69af586988..6784bfe6ab 100644
--- a/backends/graphics/opengl/opengl-graphics.cpp
+++ b/backends/graphics/opengl/opengl-graphics.cpp
@@ -273,9 +273,9 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
_gameScreen = nullptr;
#ifdef USE_RGB_COLOR
- _gameScreen = createTexture(_currentState.gameFormat);
+ _gameScreen = createSurface(_currentState.gameFormat);
#else
- _gameScreen = createTexture(Graphics::PixelFormat::createFormatCLUT8());
+ _gameScreen = createSurface(Graphics::PixelFormat::createFormatCLUT8());
#endif
assert(_gameScreen);
if (_gameScreen->hasPalette()) {
@@ -615,7 +615,7 @@ void OpenGLGraphicsManager::setMouseCursor(const void *buf, uint w, uint h, int
} else {
textureFormat = _defaultFormatAlpha;
}
- _cursor = createTexture(textureFormat, true);
+ _cursor = createSurface(textureFormat, true);
assert(_cursor);
_cursor->enableLinearFiltering(_currentState.graphicsMode == GFX_LINEAR);
}
@@ -830,7 +830,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
delete _overlay;
_overlay = nullptr;
- _overlay = createTexture(_defaultFormatAlpha);
+ _overlay = createSurface(_defaultFormatAlpha);
assert(_overlay);
// We always filter the overlay with GL_LINEAR. This assures it's
// readable in case it needs to be scaled and does not affect it
@@ -845,7 +845,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
delete _osd;
_osd = nullptr;
- _osd = createTexture(_defaultFormatAlpha);
+ _osd = createSurface(_defaultFormatAlpha);
assert(_osd);
// We always filter the osd with GL_LINEAR. This assures it's
// readable in case it needs to be scaled and does not affect it
@@ -941,40 +941,40 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
_defaultFormatAlpha = defaultFormatAlpha;
if (_gameScreen) {
- _gameScreen->recreateInternalTexture();
+ _gameScreen->recreate();
}
if (_overlay) {
- _overlay->recreateInternalTexture();
+ _overlay->recreate();
}
if (_cursor) {
- _cursor->recreateInternalTexture();
+ _cursor->recreate();
}
#ifdef USE_OSD
if (_osd) {
- _osd->recreateInternalTexture();
+ _osd->recreate();
}
#endif
}
void OpenGLGraphicsManager::notifyContextDestroy() {
if (_gameScreen) {
- _gameScreen->releaseInternalTexture();
+ _gameScreen->destroy();
}
if (_overlay) {
- _overlay->releaseInternalTexture();
+ _overlay->destroy();
}
if (_cursor) {
- _cursor->releaseInternalTexture();
+ _cursor->destroy();
}
#ifdef USE_OSD
if (_osd) {
- _osd->releaseInternalTexture();
+ _osd->destroy();
}
#endif
@@ -1028,7 +1028,7 @@ void OpenGLGraphicsManager::setMousePosition(int x, int y) {
}
}
-Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &format, bool wantAlpha) {
+Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
GLenum glIntFormat, glFormat, glType;
if (format.bytesPerPixel == 1) {
const Graphics::PixelFormat &virtFormat = wantAlpha ? _defaultFormatAlpha : _defaultFormat;
diff --git a/backends/graphics/opengl/opengl-graphics.h b/backends/graphics/opengl/opengl-graphics.h
index b6e3c1321b..40605f0259 100644
--- a/backends/graphics/opengl/opengl-graphics.h
+++ b/backends/graphics/opengl/opengl-graphics.h
@@ -40,7 +40,7 @@ namespace OpenGL {
// SurfaceSDL backend enables it and disabling it can cause issues in sdl.cpp.
#define USE_OSD 1
-class Texture;
+class Surface;
#if !USE_FORCED_GLES
class Shader;
#endif
@@ -190,15 +190,15 @@ protected:
private:
/**
- * Create a texture with the specified pixel format.
+ * Create a surface with the specified pixel format.
*
- * @param format The pixel format the Texture object should accept as
+ * @param format The pixel format the Surface object should accept as
* input.
- * @param wantAlpha For CLUT8 textures this marks whether an alpha
+ * @param wantAlpha For CLUT8 surfaces this marks whether an alpha
* channel should be used.
- * @return A pointer to the texture or nullptr on failure.
+ * @return A pointer to the surface or nullptr on failure.
*/
- Texture *createTexture(const Graphics::PixelFormat &format, bool wantAlpha = false);
+ Surface *createSurface(const Graphics::PixelFormat &format, bool wantAlpha = false);
//
// Transaction support
@@ -386,7 +386,7 @@ private:
/**
* The virtual game screen.
*/
- Texture *_gameScreen;
+ Surface *_gameScreen;
/**
* The game palette if in CLUT8 mode.
@@ -405,7 +405,7 @@ private:
/**
* The overlay screen.
*/
- Texture *_overlay;
+ Surface *_overlay;
/**
* Whether the overlay is visible or not.
@@ -424,7 +424,7 @@ private:
/**
* The cursor image.
*/
- Texture *_cursor;
+ Surface *_cursor;
/**
* X coordinate of the cursor in phyiscal coordinates.
@@ -551,7 +551,7 @@ private:
/**
* The OSD's contents.
*/
- Texture *_osd;
+ Surface *_osd;
/**
* Current opacity level of the OSD.
diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp
index 0411df3ee1..e9713eeb40 100644
--- a/backends/graphics/opengl/texture.cpp
+++ b/backends/graphics/opengl/texture.cpp
@@ -161,50 +161,15 @@ void GLTexture::updateArea(const Common::Rect &area, const Graphics::Surface &sr
_glFormat, _glType, src.getBasePtr(0, area.top)));
}
-Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
- : _format(format), _glTexture(glIntFormat, glFormat, glType),
- _textureData(), _userPixelData(), _allDirty(false) {
- recreateInternalTexture();
-}
-
-Texture::~Texture() {
- _textureData.free();
-}
-
-void Texture::releaseInternalTexture() {
- _glTexture.destroy();
-}
-
-void Texture::recreateInternalTexture() {
- _glTexture.create();
+//
+// Surface
+//
- // In case image date exists assure it will be completely refreshed next
- // time.
- if (_textureData.getPixels()) {
- flagDirty();
- }
+Surface::Surface()
+ : _allDirty(false), _dirtyArea() {
}
-void Texture::enableLinearFiltering(bool enable) {
- _glTexture.enableLinearFiltering(enable);
-}
-
-void Texture::allocate(uint width, uint height) {
- // Assure the texture can contain our user data.
- _glTexture.setSize(width, height);
-
- // In case the needed texture dimension changed we will reinitialize the
- // texture data buffer.
- if (_glTexture.getWidth() != _textureData.w || _glTexture.getHeight() != _textureData.h) {
- // Create a buffer for the texture data.
- _textureData.create(_glTexture.getWidth(), _glTexture.getHeight(), _format);
- }
-
- // Create a sub-buffer for raw access.
- _userPixelData = _textureData.getSubArea(Common::Rect(width, height));
-}
-
-void Texture::copyRectToTexture(uint x, uint y, uint w, uint h, const void *srcPtr, uint srcPitch) {
+void Surface::copyRectToTexture(uint x, uint y, uint w, uint h, const void *srcPtr, uint srcPitch) {
Graphics::Surface *dstSurf = getSurface();
assert(x + w <= dstSurf->w);
assert(y + h <= dstSurf->h);
@@ -235,13 +200,67 @@ void Texture::copyRectToTexture(uint x, uint y, uint w, uint h, const void *srcP
}
}
-void Texture::fill(uint32 color) {
+void Surface::fill(uint32 color) {
Graphics::Surface *dst = getSurface();
dst->fillRect(Common::Rect(dst->w, dst->h), color);
flagDirty();
}
+Common::Rect Surface::getDirtyArea() const {
+ if (_allDirty) {
+ return Common::Rect(getWidth(), getHeight());
+ } else {
+ return _dirtyArea;
+ }
+}
+
+//
+// Surface implementations
+//
+
+Texture::Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
+ : Surface(), _format(format), _glTexture(glIntFormat, glFormat, glType),
+ _textureData(), _userPixelData() {
+}
+
+Texture::~Texture() {
+ _textureData.free();
+}
+
+void Texture::destroy() {
+ _glTexture.destroy();
+}
+
+void Texture::recreate() {
+ _glTexture.create();
+
+ // In case image date exists assure it will be completely refreshed next
+ // time.
+ if (_textureData.getPixels()) {
+ flagDirty();
+ }
+}
+
+void Texture::enableLinearFiltering(bool enable) {
+ _glTexture.enableLinearFiltering(enable);
+}
+
+void Texture::allocate(uint width, uint height) {
+ // Assure the texture can contain our user data.
+ _glTexture.setSize(width, height);
+
+ // In case the needed texture dimension changed we will reinitialize the
+ // texture data buffer.
+ if (_glTexture.getWidth() != _textureData.w || _glTexture.getHeight() != _textureData.h) {
+ // Create a buffer for the texture data.
+ _textureData.create(_glTexture.getWidth(), _glTexture.getHeight(), _format);
+ }
+
+ // Create a sub-buffer for raw access.
+ _userPixelData = _textureData.getSubArea(Common::Rect(width, height));
+}
+
void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
// Only do any processing when the Texture is initialized.
if (!_textureData.getPixels()) {
@@ -311,14 +330,6 @@ void Texture::updateTexture() {
clearDirty();
}
-Common::Rect Texture::getDirtyArea() const {
- if (_allDirty) {
- return Common::Rect(_userPixelData.w, _userPixelData.h);
- } else {
- return _dirtyArea;
- }
-}
-
TextureCLUT8::TextureCLUT8(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format)
: Texture(glIntFormat, glFormat, glType, format), _clut8Data(), _palette(new byte[256 * format.bytesPerPixel]) {
memset(_palette, 0, sizeof(byte) * format.bytesPerPixel);
diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h
index acbfe40636..343a32b341 100644
--- a/backends/graphics/opengl/texture.h
+++ b/backends/graphics/opengl/texture.h
@@ -118,70 +118,78 @@ private:
};
/**
- * An OpenGL texture wrapper. It automatically takes care of all OpenGL
- * texture handling issues and also provides access to the texture data.
+ * Interface for OpenGL implementations of a 2D surface.
*/
-class Texture {
+class Surface {
public:
- /**
- * Create a new texture with the specific internal format.
- *
- * @param glIntFormat The internal format to use.
- * @param glFormat The input format.
- * @param glType The input type.
- * @param format The format used for the texture input.
- */
- Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format);
- virtual ~Texture();
+ Surface();
+ virtual ~Surface() {}
/**
- * Destroy the OpenGL texture name.
+ * Destroy OpenGL description of surface.
*/
- void releaseInternalTexture();
+ virtual void destroy() = 0;
/**
- * Create the OpenGL texture name and flag the whole texture as dirty.
+ * Recreate OpenGL description of surface.
*/
- void recreateInternalTexture();
+ virtual void recreate() = 0;
/**
* Enable or disable linear texture filtering.
*
* @param enable true to enable and false to disable.
*/
- void enableLinearFiltering(bool enable);
+ virtual void enableLinearFiltering(bool enable) = 0;
/**
- * Allocate texture space for the desired dimensions. This wraps any
- * handling of requirements for POT textures.
+ * Allocate storage for surface.
*
* @param width The desired logical width.
* @param height The desired logical height.
*/
- virtual void allocate(uint width, uint height);
+ virtual void allocate(uint width, uint height) = 0;
+ /**
+ * Copy image data to the surface.
+ *
+ * The format of the input data needs to match the format returned by
+ * getFormat.
+ *
+ * @param x X coordinate of upper left corner to copy data to.
+ * @param y Y coordinate of upper left corner to copy data to.
+ * @param w Width of the image data to copy.
+ * @param h Height of the image data to copy.
+ * @param src Pointer to image data.
+ * @param srcPitch The number of bytes in a row of the image data.
+ */
void copyRectToTexture(uint x, uint y, uint w, uint h, const void *src, uint srcPitch);
+ /**
+ * Fill the surface with a fixed color.
+ *
+ * @param color Color value in format returned by getFormat.
+ */
void fill(uint32 color);
- void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+ virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) = 0;
void flagDirty() { _allDirty = true; }
bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
- uint getWidth() const { return _userPixelData.w; }
- uint getHeight() const { return _userPixelData.h; }
+ virtual uint getWidth() const = 0;
+ virtual uint getHeight() const = 0;
/**
* @return The logical format of the texture data.
*/
- virtual Graphics::PixelFormat getFormat() const { return _format; }
+ virtual Graphics::PixelFormat getFormat() const = 0;
- virtual Graphics::Surface *getSurface() { return &_userPixelData; }
- virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
+ virtual Graphics::Surface *getSurface() = 0;
+ virtual const Graphics::Surface *getSurface() const = 0;
/**
- * @return Whether the texture data is using a palette.
+ * @return Whether the surface is having a palette.
*/
virtual bool hasPalette() const { return false; }
@@ -195,20 +203,62 @@ public:
virtual void setColorKey(uint colorKey) {}
virtual void setPalette(uint start, uint colors, const byte *palData) {}
protected:
+ void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
+
+ Common::Rect getDirtyArea() const;
+private:
+ bool _allDirty;
+ Common::Rect _dirtyArea;
+};
+
+/**
+ * An OpenGL texture wrapper. It automatically takes care of all OpenGL
+ * texture handling issues and also provides access to the texture data.
+ */
+class Texture : public Surface {
+public:
+ /**
+ * Create a new texture with the specific internal format.
+ *
+ * @param glIntFormat The internal format to use.
+ * @param glFormat The input format.
+ * @param glType The input type.
+ * @param format The format used for the texture input.
+ */
+ Texture(GLenum glIntFormat, GLenum glFormat, GLenum glType, const Graphics::PixelFormat &format);
+ virtual ~Texture();
+
+ virtual void destroy();
+
+ virtual void recreate();
+
+ virtual void enableLinearFiltering(bool enable);
+
+ virtual void allocate(uint width, uint height);
+
+ virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h);
+
+ virtual uint getWidth() const { return _userPixelData.w; }
+ virtual uint getHeight() const { return _userPixelData.h; }
+
+ /**
+ * @return The logical format of the texture data.
+ */
+ virtual Graphics::PixelFormat getFormat() const { return _format; }
+
+ virtual Graphics::Surface *getSurface() { return &_userPixelData; }
+ virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
+
+protected:
const Graphics::PixelFormat _format;
virtual void updateTexture();
- Common::Rect getDirtyArea() const;
private:
GLTexture _glTexture;
Graphics::Surface _textureData;
Graphics::Surface _userPixelData;
-
- bool _allDirty;
- Common::Rect _dirtyArea;
- void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
};
class TextureCLUT8 : public Texture {