OPENGL: Accelerate palette lookups with shaders.
This currently is limited to GL contexts.
This commit is contained in:
parent
de3846923c
commit
e66e9e44d3
9 changed files with 416 additions and 3 deletions
|
@ -45,6 +45,9 @@ void Context::reset() {
|
|||
NPOTSupported = false;
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
shadersSupported = false;
|
||||
multitextureSupported = false;
|
||||
framebufferObjectSupported = false;
|
||||
textureRGSupported = false;
|
||||
#endif
|
||||
|
||||
#define GL_FUNC_DEF(ret, name, param) name = nullptr;
|
||||
|
@ -216,6 +219,12 @@ void OpenGLGraphicsManager::initializeGLContext() {
|
|||
ARBVertexShader = true;
|
||||
} else if (token == "GL_ARB_fragment_shader") {
|
||||
ARBFragmentShader = true;
|
||||
} else if (token == "GL_ARB_multitexture") {
|
||||
g_context.multitextureSupported = true;
|
||||
} else if (token == "GL_ARB_texture_rg") {
|
||||
g_context.textureRGSupported = true;
|
||||
} else if (token == "GL_EXT_framebuffer_object") {
|
||||
g_context.framebufferObjectSupported = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,6 +183,9 @@ typedef GLhandleARB GLshader;
|
|||
#define GL_BGR 0x80E0
|
||||
#define GL_BGRA 0x80E1
|
||||
|
||||
#define GL_RED 0x1903
|
||||
#define GL_R8 0x8229
|
||||
|
||||
/* PixelStoreParameter */
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
|
@ -242,8 +245,18 @@ typedef GLhandleARB GLshader;
|
|||
#define GL_COMPILE_STATUS 0x8B81
|
||||
#define GL_LINK_STATUS 0x8B82
|
||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
#define GL_CURRENT_PROGRAM 0x8B8D
|
||||
|
||||
/* Textures */
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
#define GL_TEXTURE1 0x84C1
|
||||
|
||||
/* GetPName */
|
||||
#define GL_VIEWPORT 0x0BA2
|
||||
#define GL_FRAMEBUFFER_BINDING 0x8CA6
|
||||
|
||||
/* Framebuffer objects */
|
||||
#define GL_COLOR_ATTACHMENT0 0x8CE0
|
||||
#define GL_FRAMEBUFFER 0x8D40
|
||||
|
||||
#endif
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
|
||||
GL_FUNC_DEF(void, glEnable, (GLenum cap));
|
||||
GL_FUNC_DEF(void, glDisable, (GLenum cap));
|
||||
GL_FUNC_DEF(GLboolean, glIsEnabled, (GLenum cap));
|
||||
GL_FUNC_DEF(void, glClear, (GLbitfield mask));
|
||||
GL_FUNC_DEF(void, glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha));
|
||||
GL_FUNC_DEF(void, glViewport, (GLint x, GLint y, GLsizei width, GLsizei height));
|
||||
|
@ -128,10 +129,16 @@ GL_FUNC_2_DEF(void, glGetShaderiv, glGetObjectParameterivARB, (GLshader shader,
|
|||
GL_FUNC_2_DEF(void, glGetShaderInfoLog, glGetInfoLogARB, (GLshader shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog));
|
||||
GL_FUNC_2_DEF(void, glShaderSource, glShaderSourceARB, (GLshader shader, GLsizei count, const GLchar *const *string, const GLint *length));
|
||||
GL_FUNC_2_DEF(void, glCompileShader, glCompileShaderARB, (GLshader shader));
|
||||
|
||||
#if !USE_FORCED_GLES2
|
||||
GL_FUNC_2_DEF(void, glBindFramebuffer, glBindFramebufferEXT, (GLenum target, GLuint renderbuffer));
|
||||
GL_FUNC_2_DEF(void, glDeleteFramebuffers, glDeleteFramebuffersEXT, (GLsizei n, const GLuint *framebuffers));
|
||||
GL_FUNC_2_DEF(void, glGenFramebuffers, glGenFramebuffersEXT, (GLsizei n, GLuint *renderbuffers));
|
||||
GL_FUNC_2_DEF(void, glFramebufferTexture2D, glFramebufferTexture2DEXT, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level));
|
||||
GL_FUNC_2_DEF(GLenum, glCheckFramebufferStatus, glCheckFramebufferStatusEXT, (GLenum target));
|
||||
#endif
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
|
||||
GL_FUNC_2_DEF(void, glActiveTexture, glActiveTextureARB, (GLenum texture));
|
||||
#endif
|
||||
|
||||
#ifdef DEFINED_GL_EXT_FUNC_DEF
|
||||
|
|
|
@ -1031,6 +1031,12 @@ void OpenGLGraphicsManager::setMousePosition(int x, int y) {
|
|||
Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha) {
|
||||
GLenum glIntFormat, glFormat, glType;
|
||||
if (format.bytesPerPixel == 1) {
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
if (TextureCLUT8GPU::isSupportedByContext()) {
|
||||
return new TextureCLUT8GPU();
|
||||
}
|
||||
#endif
|
||||
|
||||
const Graphics::PixelFormat &virtFormat = wantAlpha ? _defaultFormatAlpha : _defaultFormat;
|
||||
const bool supported = getGLPixelFormat(virtFormat, glIntFormat, glFormat, glType);
|
||||
if (!supported) {
|
||||
|
|
|
@ -111,6 +111,15 @@ struct Context {
|
|||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
/** Whether shader support is available or not. */
|
||||
bool shadersSupported;
|
||||
|
||||
/** Whether multi texture support is available or not. */
|
||||
bool multitextureSupported;
|
||||
|
||||
/** Whether (GLES2) RG texture formats are supported. */
|
||||
bool textureRGSupported;
|
||||
|
||||
/** Whether FBO support is available or not. */
|
||||
bool framebufferObjectSupported;
|
||||
#endif
|
||||
|
||||
#define GL_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
|
||||
|
|
|
@ -171,6 +171,16 @@ void Shader::activate(const GLfloat *projectionMatrix) {
|
|||
GL_CALL(glUniform1i(_textureLocation, 0));
|
||||
}
|
||||
|
||||
GLint Shader::getUniformLocation(const char *name) const {
|
||||
GLint result = -1;
|
||||
GL_ASSIGN(result, glGetUniformLocation(_program, name));
|
||||
return result;
|
||||
}
|
||||
|
||||
void Shader::setUniformI(GLint location, GLint value) {
|
||||
GL_CALL(glUniform1i(location, value));
|
||||
}
|
||||
|
||||
GLshader Shader::compileShader(const char *source, GLenum shaderType) {
|
||||
GLshader handle;
|
||||
GL_ASSIGN(handle, glCreateShader(shaderType));
|
||||
|
|
|
@ -71,6 +71,24 @@ public:
|
|||
* @param projectionMatrix Projection matrix to use.
|
||||
*/
|
||||
void activate(const GLfloat *projectionMatrix);
|
||||
|
||||
/**
|
||||
* Return location for uniform with given name.
|
||||
*
|
||||
* @param name Name of the uniform to look up in the shader.
|
||||
* @return The location or -1 if uniform was not found.
|
||||
*/
|
||||
GLint getUniformLocation(const char *name) const;
|
||||
|
||||
/**
|
||||
* Bind value to uniform.
|
||||
*
|
||||
* Note: this only works when the shader is actived by activate.
|
||||
*
|
||||
* @param location Location of the uniform.
|
||||
* @param value The value to be set.
|
||||
*/
|
||||
void setUniformI(GLint location, GLint value);
|
||||
protected:
|
||||
/**
|
||||
* Vertex shader sources.
|
||||
|
|
|
@ -504,4 +504,274 @@ void TextureRGB555::updateTexture() {
|
|||
}
|
||||
#endif // !USE_FORCED_GL
|
||||
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
namespace {
|
||||
const char *const g_lookUpFragmentShaderGL =
|
||||
"varying vec2 texCoord;\n"
|
||||
"varying vec4 blendColor;\n"
|
||||
"\n"
|
||||
"uniform sampler2D texture;\n"
|
||||
"uniform sampler2D palette;\n"
|
||||
"\n"
|
||||
"const float adjustFactor = 255.0 / 256.0 + 1.0 / (2.0 * 256.0);"
|
||||
"\n"
|
||||
"void main(void) {\n"
|
||||
"\tvec4 index = texture2D(texture, texCoord);\n"
|
||||
"\tgl_FragColor = blendColor * texture2D(palette, vec2(index.x * adjustFactor, 0.0));\n"
|
||||
"}\n";
|
||||
} // End of anonymous namespace
|
||||
|
||||
TextureCLUT8GPU::TextureCLUT8GPU()
|
||||
: _clut8Texture(GL_R8, GL_RED, GL_UNSIGNED_BYTE),
|
||||
_paletteTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
|
||||
_glTexture(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
|
||||
_glFBO(0), _clut8Vertices(), _projectionMatrix(),
|
||||
_lookUpShader(nullptr), _paletteLocation(-1),
|
||||
_clut8Data(), _userPixelData(), _palette(), _paletteDirty(false) {
|
||||
// Allocate space for 256 colors.
|
||||
_paletteTexture.setSize(256, 1);
|
||||
|
||||
_lookUpShader = new Shader(g_defaultVertexShader, g_lookUpFragmentShaderGL);
|
||||
_lookUpShader->recreate();
|
||||
_paletteLocation = _lookUpShader->getUniformLocation("palette");
|
||||
|
||||
setupFBO();
|
||||
}
|
||||
|
||||
TextureCLUT8GPU::~TextureCLUT8GPU() {
|
||||
delete _lookUpShader;
|
||||
GL_CALL_SAFE(glDeleteFramebuffers, (1, &_glFBO));
|
||||
_clut8Data.free();
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::destroy() {
|
||||
_clut8Texture.destroy();
|
||||
_paletteTexture.destroy();
|
||||
_glTexture.destroy();
|
||||
_lookUpShader->destroy();
|
||||
|
||||
GL_CALL(glDeleteFramebuffers(1, &_glFBO));
|
||||
_glFBO = 0;
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::recreate() {
|
||||
_clut8Texture.create();
|
||||
_paletteTexture.create();
|
||||
_glTexture.create();
|
||||
_lookUpShader->recreate();
|
||||
_paletteLocation = _lookUpShader->getUniformLocation("palette");
|
||||
setupFBO();
|
||||
|
||||
// In case image date exists assure it will be completely refreshed next
|
||||
// time.
|
||||
if (_clut8Data.getPixels()) {
|
||||
flagDirty();
|
||||
_paletteDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::enableLinearFiltering(bool enable) {
|
||||
_glTexture.enableLinearFiltering(enable);
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::allocate(uint width, uint height) {
|
||||
// Assure the texture can contain our user data.
|
||||
_clut8Texture.setSize(width, height);
|
||||
_glTexture.setSize(width, height);
|
||||
|
||||
// In case the needed texture dimension changed we will reinitialize the
|
||||
// texture data buffer.
|
||||
if (_clut8Texture.getWidth() != _clut8Data.w || _clut8Texture.getHeight() != _clut8Data.h) {
|
||||
// Create a buffer for the texture data.
|
||||
_clut8Data.create(_clut8Texture.getWidth(), _clut8Texture.getHeight(), Graphics::PixelFormat::createFormatCLUT8());
|
||||
}
|
||||
|
||||
// Create a sub-buffer for raw access.
|
||||
_userPixelData = _clut8Data.getSubArea(Common::Rect(width, height));
|
||||
|
||||
// Setup structures for internal rendering to _glTexture.
|
||||
_clut8Vertices[0] = 0;
|
||||
_clut8Vertices[1] = 0;
|
||||
|
||||
_clut8Vertices[2] = width;
|
||||
_clut8Vertices[3] = 0;
|
||||
|
||||
_clut8Vertices[4] = 0;
|
||||
_clut8Vertices[5] = height;
|
||||
|
||||
_clut8Vertices[6] = width;
|
||||
_clut8Vertices[7] = height;
|
||||
|
||||
_projectionMatrix[ 0] = 2.0f / _glTexture.getWidth();
|
||||
_projectionMatrix[ 1] = 0.0f;
|
||||
_projectionMatrix[ 2] = 0.0f;
|
||||
_projectionMatrix[ 3] = 0.0f;
|
||||
|
||||
_projectionMatrix[ 4] = 0.0f;
|
||||
_projectionMatrix[ 5] = 2.0f / _glTexture.getHeight();
|
||||
_projectionMatrix[ 6] = 0.0f;
|
||||
_projectionMatrix[ 7] = 0.0f;
|
||||
|
||||
_projectionMatrix[ 8] = 0.0f;
|
||||
_projectionMatrix[ 9] = 0.0f;
|
||||
_projectionMatrix[10] = 0.0f;
|
||||
_projectionMatrix[11] = 0.0f;
|
||||
|
||||
_projectionMatrix[12] = -1.0f;
|
||||
_projectionMatrix[13] = -1.0f;
|
||||
_projectionMatrix[14] = 0.0f;
|
||||
_projectionMatrix[15] = 1.0f;
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
|
||||
// Only do any processing when the Texture is initialized.
|
||||
if (!_clut8Data.getPixels()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First update any potentional changes.
|
||||
updateTextures();
|
||||
|
||||
// Set the texture.
|
||||
_glTexture.bind();
|
||||
|
||||
// Calculate the screen rect where the texture will be drawn.
|
||||
const GLfloat vertices[4*2] = {
|
||||
x, y,
|
||||
x + w, y,
|
||||
x, y + h,
|
||||
x + w, y + h
|
||||
};
|
||||
|
||||
// Setup coordinates for drawing.
|
||||
g_context.setDrawCoordinates(vertices, _glTexture.getTexCoords());
|
||||
|
||||
// Draw the texture to the screen buffer.
|
||||
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
}
|
||||
|
||||
Graphics::PixelFormat TextureCLUT8GPU::getFormat() const {
|
||||
return Graphics::PixelFormat::createFormatCLUT8();
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::setColorKey(uint colorKey) {
|
||||
_palette[colorKey * 4 + 3] = 0x00;
|
||||
|
||||
_paletteDirty = true;
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::setPalette(uint start, uint colors, const byte *palData) {
|
||||
byte *dst = _palette + start * 4;
|
||||
|
||||
while (colors-- > 0) {
|
||||
memcpy(dst, palData, 3);
|
||||
dst[3] = 0xFF;
|
||||
|
||||
dst += 4;
|
||||
palData += 3;
|
||||
}
|
||||
|
||||
_paletteDirty = true;
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::updateTextures() {
|
||||
const bool needLookUp = Surface::isDirty() || _paletteDirty;
|
||||
|
||||
// Update CLUT8 texture if necessary.
|
||||
if (Surface::isDirty()) {
|
||||
_clut8Texture.updateArea(getDirtyArea(), _clut8Data);
|
||||
clearDirty();
|
||||
}
|
||||
|
||||
// Update palette if necessary.
|
||||
if (_paletteDirty) {
|
||||
Graphics::Surface palSurface;
|
||||
palSurface.init(256, 1, 256, _palette,
|
||||
#ifdef SCUMM_LITTLE_ENDIAN
|
||||
Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24) // ABGR8888
|
||||
#else
|
||||
Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0) // RGBA8888
|
||||
#endif
|
||||
);
|
||||
|
||||
_paletteTexture.updateArea(Common::Rect(256, 1), palSurface);
|
||||
_paletteDirty = false;
|
||||
}
|
||||
|
||||
// In case any data changed, do color look up and save result in _glTexture.
|
||||
if (needLookUp) {
|
||||
lookUpColors();
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::lookUpColors() {
|
||||
// Save old state.
|
||||
GLint oldProgram = 0;
|
||||
GL_CALL(glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgram));
|
||||
|
||||
GLint viewport[4];
|
||||
GL_CALL(glGetIntegerv(GL_VIEWPORT, viewport));
|
||||
|
||||
GLboolean scissorState;
|
||||
GL_ASSIGN(scissorState, glIsEnabled(GL_SCISSOR_TEST));
|
||||
GLboolean blendState;
|
||||
GL_ASSIGN(blendState, glIsEnabled(GL_BLEND));
|
||||
|
||||
GLint oldFBO = 0;
|
||||
GL_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO));
|
||||
|
||||
// Update state.
|
||||
GL_CALL(glViewport(0, 0, _glTexture.getWidth(), _glTexture.getHeight()));
|
||||
GL_CALL(glDisable(GL_SCISSOR_TEST));
|
||||
GL_CALL(glDisable(GL_BLEND));
|
||||
|
||||
// Bind framebuffer.
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
|
||||
|
||||
// Set the palette texture.
|
||||
GL_CALL(glActiveTexture(GL_TEXTURE1));
|
||||
_paletteTexture.bind();
|
||||
|
||||
// Set the clut8 texture.
|
||||
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
||||
_clut8Texture.bind();
|
||||
|
||||
// Do color look up.
|
||||
_lookUpShader->activate(_projectionMatrix);
|
||||
_lookUpShader->setUniformI(_paletteLocation, 1);
|
||||
g_context.setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
|
||||
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
|
||||
// Restore old state.
|
||||
GL_CALL(glUseProgram(oldProgram));
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, oldFBO));
|
||||
|
||||
if (blendState) {
|
||||
GL_CALL(glEnable(GL_BLEND));
|
||||
}
|
||||
if (scissorState) {
|
||||
GL_CALL(glEnable(GL_SCISSOR_TEST));
|
||||
}
|
||||
GL_CALL(glViewport(viewport[0], viewport[1], viewport[2], viewport[3]));
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::setupFBO() {
|
||||
// Allocate framebuffer object if necessary.
|
||||
if (!_glFBO) {
|
||||
GL_CALL(glGenFramebuffers(1, &_glFBO));
|
||||
}
|
||||
|
||||
// Save old FBO.
|
||||
GLint oldFBO = 0;
|
||||
GL_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO));
|
||||
|
||||
// Attach destination texture to FBO.
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, _glFBO));
|
||||
GL_CALL(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _glTexture.getGLTexture(), 0));
|
||||
|
||||
// Restore old FBO.
|
||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, oldFBO));
|
||||
}
|
||||
#endif // !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
|
||||
} // End of namespace OpenGL
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
namespace OpenGL {
|
||||
|
||||
class Shader;
|
||||
|
||||
/**
|
||||
* A simple GL texture object abstraction.
|
||||
*
|
||||
|
@ -104,6 +106,14 @@ public:
|
|||
* Obtain texture coordinates for rectangular drawing.
|
||||
*/
|
||||
const GLfloat *getTexCoords() const { return _texCoords; }
|
||||
|
||||
/**
|
||||
* Obtain texture name.
|
||||
*
|
||||
* Beware that the texture name changes whenever create is used.
|
||||
* destroy will invalidate the texture name.
|
||||
*/
|
||||
GLuint getGLTexture() const { return _glTexture; }
|
||||
private:
|
||||
const GLenum _glIntFormat;
|
||||
const GLenum _glFormat;
|
||||
|
@ -175,7 +185,7 @@ public:
|
|||
virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) = 0;
|
||||
|
||||
void flagDirty() { _allDirty = true; }
|
||||
bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
|
||||
virtual bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
|
||||
|
||||
virtual uint getWidth() const = 0;
|
||||
virtual uint getHeight() const = 0;
|
||||
|
@ -307,6 +317,67 @@ private:
|
|||
};
|
||||
#endif // !USE_FORCED_GL
|
||||
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
class TextureCLUT8GPU : public Surface {
|
||||
public:
|
||||
TextureCLUT8GPU();
|
||||
virtual ~TextureCLUT8GPU();
|
||||
|
||||
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 bool isDirty() const { return _paletteDirty || Surface::isDirty(); }
|
||||
|
||||
virtual uint getWidth() const { return _userPixelData.w; }
|
||||
virtual uint getHeight() const { return _userPixelData.h; }
|
||||
|
||||
virtual Graphics::PixelFormat getFormat() const;
|
||||
|
||||
virtual bool hasPalette() const { return true; }
|
||||
|
||||
virtual void setColorKey(uint colorKey);
|
||||
virtual void setPalette(uint start, uint colors, const byte *palData);
|
||||
|
||||
virtual Graphics::Surface *getSurface() { return &_userPixelData; }
|
||||
virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
|
||||
|
||||
static bool isSupportedByContext() {
|
||||
return g_context.shadersSupported
|
||||
&& g_context.multitextureSupported
|
||||
&& g_context.textureRGSupported
|
||||
&& g_context.framebufferObjectSupported;
|
||||
}
|
||||
private:
|
||||
void updateTextures();
|
||||
void lookUpColors();
|
||||
|
||||
GLTexture _clut8Texture;
|
||||
GLTexture _paletteTexture;
|
||||
GLTexture _glTexture;
|
||||
|
||||
void setupFBO();
|
||||
GLuint _glFBO;
|
||||
GLfloat _clut8Vertices[4*2];
|
||||
GLfloat _projectionMatrix[4*4];
|
||||
|
||||
Shader *_lookUpShader;
|
||||
GLint _paletteLocation;
|
||||
|
||||
Graphics::Surface _clut8Data;
|
||||
Graphics::Surface _userPixelData;
|
||||
|
||||
byte _palette[4 * 256];
|
||||
bool _paletteDirty;
|
||||
};
|
||||
#endif // !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
|
||||
} // End of namespace OpenGL
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue