/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef BACKENDS_GRAPHICS3D_ANDROID_TEXTURE_H
#define BACKENDS_GRAPHICS3D_ANDROID_TEXTURE_H
#define GL_GLEXT_PROTOTYPES
#include
#include "graphics/surface.h"
#include "graphics/pixelformat.h"
#include "common/rect.h"
#include "common/array.h"
namespace OpenGL {
class Shader;
}
class GLESBaseTexture {
public:
static void initGL();
static void unbindShader();
protected:
GLESBaseTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat pixelFormat);
public:
virtual ~GLESBaseTexture();
void release();
void reinit();
void setLinearFilter(bool value);
virtual void allocBuffer(GLuint w, GLuint h);
virtual void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
const void *buf, int pitch_buf) = 0;
virtual void fillBuffer(uint32 color) = 0;
void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
}
void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
inline void setDrawRect(const Common::Rect &rect) {
_draw_rect = rect;
}
inline void setDrawRect(int16 w, int16 h) {
_draw_rect = Common::Rect(w, h);
}
inline void setDrawRect(int16 x1, int16 y1, int16 x2, int16 y2) {
_draw_rect = Common::Rect(x1, y1, x2, y2);
}
inline const Common::Rect &getDrawRect() const {
return _draw_rect;
}
inline void drawTextureRect() {
drawTexture(_draw_rect.left, _draw_rect.top,
_draw_rect.width(), _draw_rect.height());
}
inline void drawTextureOrigin() {
drawTexture(0, 0, _surface.w, _surface.h);
}
inline GLuint width() const {
return _surface.w;
}
inline GLuint height() const {
return _surface.h;
}
inline GLuint texWidth() const {
return _texture_width;
}
inline GLuint texHeight() const {
return _texture_height;
}
inline uint16 pitch() const {
return _surface.pitch;
}
inline bool isEmpty() const {
return _surface.w == 0 || _surface.h == 0;
}
inline const Graphics::Surface *surface_const() const {
return &_surface;
}
inline Graphics::Surface *surface() {
setDirty();
return &_surface;
}
virtual void setPalette(const byte *colors, uint start, uint num) = 0;
virtual void setKeycolor(byte color) = 0;
virtual void grabPalette(byte *colors, uint start, uint num) const = 0;
inline bool hasPalette() const {
return _palettePixelFormat.bytesPerPixel > 0;
}
inline bool dirty() const {
return _all_dirty || !_dirty_rect.isEmpty();
}
virtual const Graphics::PixelFormat &getPixelFormat() const;
inline const Graphics::PixelFormat &getPalettePixelFormat() const {
return _palettePixelFormat;
}
GLuint getTextureName() const {
return _texture_name;
}
void setGameTexture() {
_is_game_texture = true;
}
protected:
void initSize();
virtual void *prepareTextureBuffer(const Common::Rect &rect) = 0;
inline void setDirty() {
_all_dirty = true;
}
inline void clearDirty() {
_all_dirty = false;
_dirty_rect.top = 0;
_dirty_rect.left = 0;
_dirty_rect.bottom = 0;
_dirty_rect.right = 0;
}
inline void setDirtyRect(const Common::Rect &r) {
if (!_all_dirty) {
if (_dirty_rect.isEmpty()) {
_dirty_rect = r;
} else {
_dirty_rect.extend(r);
}
}
}
GLenum _glFormat;
GLenum _glType;
GLint _glFilter;
GLuint _texture_name;
Graphics::Surface _surface;
GLuint _texture_width;
GLuint _texture_height;
Common::Rect _draw_rect;
bool _all_dirty;
Common::Rect _dirty_rect;
Graphics::PixelFormat _pixelFormat;
Graphics::PixelFormat _palettePixelFormat;
bool _is_game_texture;
static bool _npot_supported;
static OpenGL::Shader *_box_shader;
static GLuint _verticesVBO;
};
class GLESTexture : public GLESBaseTexture {
protected:
GLESTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat pixelFormat);
public:
virtual ~GLESTexture();
void allocBuffer(GLuint w, GLuint h) override;
void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
const void *buf, int pitch_buf) override;
void fillBuffer(uint32 color) override;
void setPalette(const byte *colors, uint start, uint num) override {}
void setKeycolor(byte color) override {};
void grabPalette(byte *colors, uint start, uint num) const override {}
void readPixels();
protected:
void *prepareTextureBuffer(const Common::Rect &rect) override;
byte *_pixels;
byte *_buf;
};
// RGBA4444 texture
class GLES4444Texture : public GLESTexture {
public:
GLES4444Texture() : GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixelFormat()) {}
virtual ~GLES4444Texture() {}
static Graphics::PixelFormat pixelFormat() {
return Graphics::PixelFormat(2, 4, 4, 4, 4, 12, 8, 4, 0);
}
};
// RGBA5551 texture
class GLES5551Texture : public GLESTexture {
public:
GLES5551Texture() : GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixelFormat()) {}
virtual ~GLES5551Texture() {}
static inline Graphics::PixelFormat pixelFormat() {
return Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0);
}
};
// RGB565 texture
class GLES565Texture : public GLESTexture {
public:
GLES565Texture() : GLESTexture(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixelFormat()) {}
virtual ~GLES565Texture() {}
static inline Graphics::PixelFormat pixelFormat() {
return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
}
};
class GLES888Texture : public GLESTexture {
public:
GLES888Texture() : GLESTexture(GL_RGB, GL_UNSIGNED_BYTE, pixelFormat()) {}
virtual ~GLES888Texture() {}
static Graphics::PixelFormat pixelFormat() {
#ifdef SCUMM_BIG_ENDIAN
return Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0);
#else
return Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0);
#endif
}
};
class GLES8888Texture : public GLESTexture {
public:
GLES8888Texture() : GLESTexture(GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat()) {}
virtual ~GLES8888Texture() {}
static Graphics::PixelFormat pixelFormat() {
#ifdef SCUMM_BIG_ENDIAN
return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
#else
return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
#endif
}
};
class GLESFakePaletteTexture : public GLESBaseTexture {
protected:
GLESFakePaletteTexture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat pixelFormat);
public:
virtual ~GLESFakePaletteTexture();
void allocBuffer(GLuint w, GLuint h) override;
void updateBuffer(GLuint x, GLuint y, GLuint width, GLuint height,
const void *buf, int pitch_buf) override;
void fillBuffer(uint32 color) override;
const Graphics::PixelFormat &getPixelFormat() const override {
return _fake_format;
}
protected:
Graphics::PixelFormat _fake_format;
byte *_pixels;
};
class GLESFakePalette16Texture : public GLESFakePaletteTexture {
protected:
GLESFakePalette16Texture(GLenum glFormat, GLenum glType,
Graphics::PixelFormat pixelFormat);
public:
virtual ~GLESFakePalette16Texture();
void allocBuffer(GLuint w, GLuint h) override;
void setPalette(const byte *colors, uint start, uint num) override;
void grabPalette(byte *colors, uint start, uint num) const override;
protected:
void *prepareTextureBuffer(const Common::Rect &rect) override;
uint16 *_palette;
uint16 *_buf;
};
class GLESFakePalette565Texture : public GLESFakePalette16Texture {
public:
GLESFakePalette565Texture();
virtual ~GLESFakePalette565Texture() {}
void setKeycolor(byte color) override {};
};
class GLESFakePalette5551Texture : public GLESFakePalette16Texture {
public:
GLESFakePalette5551Texture();
virtual ~GLESFakePalette5551Texture() {}
void setKeycolor(byte color) override;
protected:
byte _keycolor;
};
class GLESFakePalette888Texture : public GLESFakePaletteTexture {
public:
GLESFakePalette888Texture();
virtual ~GLESFakePalette888Texture();
void allocBuffer(GLuint w, GLuint h) override;
void setPalette(const byte *colors, uint start, uint num) override;
void setKeycolor(byte color) override {};
void grabPalette(byte *colors, uint start, uint num) const override;
protected:
void *prepareTextureBuffer(const Common::Rect &rect) override;
byte *_palette;
byte *_buf;
};
class GLESFakePalette8888Texture : public GLESFakePaletteTexture {
public:
GLESFakePalette8888Texture();
virtual ~GLESFakePalette8888Texture();
void allocBuffer(GLuint w, GLuint h) override;
void setPalette(const byte *colors, uint start, uint num) override;
void setKeycolor(byte color) override;
void grabPalette(byte *colors, uint start, uint num) const override;
protected:
void *prepareTextureBuffer(const Common::Rect &rect) override;
uint32 *_palette;
uint32 *_buf;
byte _keycolor;
};
#endif