OPENGL: Implement texture drawing in Pipeline instead of Surface.
This commit is contained in:
parent
0fe580d10c
commit
b17c035642
5 changed files with 72 additions and 99 deletions
|
@ -370,6 +370,14 @@ void OpenGLGraphicsManager::updateScreen() {
|
|||
}
|
||||
_forceRedraw = false;
|
||||
|
||||
// Update changes to textures.
|
||||
_gameScreen->updateGLTexture();
|
||||
if (_cursor) {
|
||||
_cursor->updateGLTexture();
|
||||
}
|
||||
_overlay->updateGLTexture();
|
||||
_osd->updateGLTexture();
|
||||
|
||||
// Clear the screen buffer.
|
||||
if (_scissorOverride && !_overlayVisible) {
|
||||
// In certain cases we need to assure that the whole screen area is
|
||||
|
@ -388,11 +396,11 @@ void OpenGLGraphicsManager::updateScreen() {
|
|||
const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
|
||||
|
||||
// First step: Draw the (virtual) game screen.
|
||||
_gameScreen->draw(_displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
|
||||
g_context.activePipeline->drawTexture(_gameScreen->getGLTexture(), _displayX, _displayY + shakeOffset, _displayWidth, _displayHeight);
|
||||
|
||||
// Second step: Draw the overlay if visible.
|
||||
if (_overlayVisible) {
|
||||
_overlay->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
|
||||
g_context.activePipeline->drawTexture(_overlay->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
|
||||
}
|
||||
|
||||
// Third step: Draw the cursor if visible.
|
||||
|
@ -401,7 +409,8 @@ void OpenGLGraphicsManager::updateScreen() {
|
|||
// visible.
|
||||
const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
|
||||
|
||||
_cursor->draw(_cursorDisplayX - _cursorHotspotXScaled,
|
||||
g_context.activePipeline->drawTexture(_cursor->getGLTexture(),
|
||||
_cursorDisplayX - _cursorHotspotXScaled,
|
||||
_cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
|
||||
_cursorWidthScaled, _cursorHeightScaled);
|
||||
}
|
||||
|
@ -427,7 +436,7 @@ void OpenGLGraphicsManager::updateScreen() {
|
|||
g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
|
||||
|
||||
// Draw the OSD texture.
|
||||
_osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight);
|
||||
g_context.activePipeline->drawTexture(_osd->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
|
||||
|
||||
// Reset color.
|
||||
g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
|
|
@ -67,9 +67,12 @@ void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
|||
GL_CALL(glColor4f(r, g, b, a));
|
||||
}
|
||||
|
||||
void FixedPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
|
||||
GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
|
||||
GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
|
||||
void FixedPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
|
||||
texture.bind();
|
||||
|
||||
GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texture.getTexCoords()));
|
||||
GL_CALL(glVertexPointer(2, GL_FLOAT, 0, coordinates));
|
||||
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
}
|
||||
|
||||
void FixedPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
|
||||
|
@ -110,9 +113,12 @@ void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
|||
GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
|
||||
}
|
||||
|
||||
void ShaderPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) {
|
||||
GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
|
||||
GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
|
||||
void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
|
||||
texture.bind();
|
||||
|
||||
GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texture.getTexCoords()));
|
||||
GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, coordinates));
|
||||
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
}
|
||||
|
||||
void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define BACKENDS_GRAPHICS_OPENGL_PIEPLINE_H
|
||||
|
||||
#include "backends/graphics/opengl/opengl-sys.h"
|
||||
#include "backends/graphics/opengl/texture.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
|
@ -87,13 +88,22 @@ public:
|
|||
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) = 0;
|
||||
|
||||
/**
|
||||
* Setup coordinates for drawing with glDrawArrays.
|
||||
* Draw a texture rectangle to the currently active framebuffer.
|
||||
*
|
||||
* @param vertices The list of vertices, 2 coordinates for each vertex.
|
||||
* @param texCoords The list of texture coordinates, 2 coordinates for
|
||||
* each vertex.
|
||||
* @param texture Texture to use for drawing.
|
||||
* @param coordinates x1, y1, x2, y2 coordinates where to draw the texture.
|
||||
*/
|
||||
virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) = 0;
|
||||
virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates) = 0;
|
||||
|
||||
void drawTexture(const GLTexture &texture, GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
|
||||
const GLfloat coordinates[4*2] = {
|
||||
x, y,
|
||||
x + w, y,
|
||||
x, y + h,
|
||||
x + w, y + h
|
||||
};
|
||||
drawTexture(texture, coordinates);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the projection matrix.
|
||||
|
@ -113,7 +123,7 @@ public:
|
|||
|
||||
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
|
||||
virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
|
||||
virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
|
||||
|
||||
virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
|
||||
};
|
||||
|
@ -130,7 +140,7 @@ public:
|
|||
|
||||
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
|
||||
virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
|
||||
virtual void drawTexture(const GLTexture &texture, const GLfloat *coordinates);
|
||||
|
||||
virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ void GLTexture::create() {
|
|||
}
|
||||
}
|
||||
|
||||
void GLTexture::bind() {
|
||||
void GLTexture::bind() const {
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture));
|
||||
}
|
||||
|
||||
|
@ -263,34 +263,7 @@ void Texture::allocate(uint width, uint height) {
|
|||
_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()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First update any potentional changes.
|
||||
updateTexture();
|
||||
|
||||
// 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.activePipeline->setDrawCoordinates(vertices, _glTexture.getTexCoords());
|
||||
|
||||
// Draw the texture to the screen buffer.
|
||||
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
}
|
||||
|
||||
void Texture::updateTexture() {
|
||||
void Texture::updateGLTexture() {
|
||||
if (!isDirty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -418,7 +391,7 @@ inline void doPaletteLookUp(PixelType *dst, const byte *src, uint width, uint he
|
|||
}
|
||||
} // End of anonymous namespace
|
||||
|
||||
void TextureCLUT8::updateTexture() {
|
||||
void TextureCLUT8::updateGLTexture() {
|
||||
if (!isDirty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -443,7 +416,7 @@ void TextureCLUT8::updateTexture() {
|
|||
}
|
||||
|
||||
// Do generic handling of updating the texture.
|
||||
Texture::updateTexture();
|
||||
Texture::updateGLTexture();
|
||||
}
|
||||
|
||||
#if !USE_FORCED_GL
|
||||
|
@ -502,7 +475,7 @@ void TextureRGB555::updateTexture() {
|
|||
}
|
||||
|
||||
// Do generic handling of updating the texture.
|
||||
Texture::updateTexture();
|
||||
Texture::updateGLTexture();
|
||||
}
|
||||
#endif // !USE_FORCED_GL
|
||||
|
||||
|
@ -582,33 +555,6 @@ void TextureCLUT8GPU::allocate(uint width, uint height) {
|
|||
_clut8Vertices[7] = height;
|
||||
}
|
||||
|
||||
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.
|
||||
_target->getTexture()->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.activePipeline->setDrawCoordinates(vertices, _target->getTexture()->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();
|
||||
}
|
||||
|
@ -633,7 +579,11 @@ void TextureCLUT8GPU::setPalette(uint start, uint colors, const byte *palData) {
|
|||
_paletteDirty = true;
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::updateTextures() {
|
||||
const GLTexture &TextureCLUT8GPU::getGLTexture() const {
|
||||
return *_target->getTexture();
|
||||
}
|
||||
|
||||
void TextureCLUT8GPU::updateGLTexture() {
|
||||
const bool needLookUp = Surface::isDirty() || _paletteDirty;
|
||||
|
||||
// Update CLUT8 texture if necessary.
|
||||
|
@ -674,14 +624,10 @@ void TextureCLUT8GPU::lookUpColors() {
|
|||
// 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.
|
||||
g_context.activePipeline->setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
|
||||
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
g_context.activePipeline->drawTexture(_clut8Texture, _clut8Vertices);
|
||||
|
||||
// Restore old state.
|
||||
g_context.activePipeline->setShader(oldShader);
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
/**
|
||||
* Bind the texture to the active texture unit.
|
||||
*/
|
||||
void bind();
|
||||
void bind() const;
|
||||
|
||||
/**
|
||||
* Sets the size of the texture in pixels.
|
||||
|
@ -182,8 +182,6 @@ public:
|
|||
*/
|
||||
void fill(uint32 color);
|
||||
|
||||
virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) = 0;
|
||||
|
||||
void flagDirty() { _allDirty = true; }
|
||||
virtual bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
|
||||
|
||||
|
@ -212,6 +210,16 @@ public:
|
|||
*/
|
||||
virtual void setColorKey(uint colorKey) {}
|
||||
virtual void setPalette(uint start, uint colors, const byte *palData) {}
|
||||
|
||||
/**
|
||||
* Update underlying OpenGL texture to reflect current state.
|
||||
*/
|
||||
virtual void updateGLTexture() = 0;
|
||||
|
||||
/**
|
||||
* Obtain underlying OpenGL texture.
|
||||
*/
|
||||
virtual const GLTexture &getGLTexture() const = 0;
|
||||
protected:
|
||||
void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
|
||||
|
||||
|
@ -246,8 +254,6 @@ public:
|
|||
|
||||
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; }
|
||||
|
||||
|
@ -259,11 +265,11 @@ public:
|
|||
virtual Graphics::Surface *getSurface() { return &_userPixelData; }
|
||||
virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
|
||||
|
||||
virtual void updateGLTexture();
|
||||
virtual const GLTexture &getGLTexture() const { return _glTexture; }
|
||||
protected:
|
||||
const Graphics::PixelFormat _format;
|
||||
|
||||
virtual void updateTexture();
|
||||
|
||||
private:
|
||||
GLTexture _glTexture;
|
||||
|
||||
|
@ -288,9 +294,7 @@ public:
|
|||
virtual Graphics::Surface *getSurface() { return &_clut8Data; }
|
||||
virtual const Graphics::Surface *getSurface() const { return &_clut8Data; }
|
||||
|
||||
protected:
|
||||
virtual void updateTexture();
|
||||
|
||||
virtual void updateGLTexture();
|
||||
private:
|
||||
Graphics::Surface _clut8Data;
|
||||
byte *_palette;
|
||||
|
@ -309,9 +313,7 @@ public:
|
|||
virtual Graphics::Surface *getSurface() { return &_rgb555Data; }
|
||||
virtual const Graphics::Surface *getSurface() const { return &_rgb555Data; }
|
||||
|
||||
protected:
|
||||
virtual void updateTexture();
|
||||
|
||||
private:
|
||||
Graphics::Surface _rgb555Data;
|
||||
};
|
||||
|
@ -333,8 +335,6 @@ public:
|
|||
|
||||
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; }
|
||||
|
@ -350,13 +350,15 @@ public:
|
|||
virtual Graphics::Surface *getSurface() { return &_userPixelData; }
|
||||
virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
|
||||
|
||||
virtual void updateGLTexture();
|
||||
virtual const GLTexture &getGLTexture() const;
|
||||
|
||||
static bool isSupportedByContext() {
|
||||
return g_context.shadersSupported
|
||||
&& g_context.multitextureSupported
|
||||
&& g_context.framebufferObjectSupported;
|
||||
}
|
||||
private:
|
||||
void updateTextures();
|
||||
void lookUpColors();
|
||||
|
||||
GLTexture _clut8Texture;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue