OPENGL: Implement texture drawing in Pipeline instead of Surface.

This commit is contained in:
Johannes Schickel 2016-01-06 16:52:03 +01:00
parent 0fe580d10c
commit b17c035642
5 changed files with 72 additions and 99 deletions

View file

@ -370,6 +370,14 @@ void OpenGLGraphicsManager::updateScreen() {
} }
_forceRedraw = false; _forceRedraw = false;
// Update changes to textures.
_gameScreen->updateGLTexture();
if (_cursor) {
_cursor->updateGLTexture();
}
_overlay->updateGLTexture();
_osd->updateGLTexture();
// Clear the screen buffer. // Clear the screen buffer.
if (_scissorOverride && !_overlayVisible) { if (_scissorOverride && !_overlayVisible) {
// In certain cases we need to assure that the whole screen area is // 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(); const GLfloat shakeOffset = _gameScreenShakeOffset * (GLfloat)_displayHeight / _gameScreen->getHeight();
// First step: Draw the (virtual) game screen. // 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. // Second step: Draw the overlay if visible.
if (_overlayVisible) { 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. // Third step: Draw the cursor if visible.
@ -401,9 +409,10 @@ void OpenGLGraphicsManager::updateScreen() {
// visible. // visible.
const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset; const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset;
_cursor->draw(_cursorDisplayX - _cursorHotspotXScaled, g_context.activePipeline->drawTexture(_cursor->getGLTexture(),
_cursorDisplayY - _cursorHotspotYScaled + cursorOffset, _cursorDisplayX - _cursorHotspotXScaled,
_cursorWidthScaled, _cursorHeightScaled); _cursorDisplayY - _cursorHotspotYScaled + cursorOffset,
_cursorWidthScaled, _cursorHeightScaled);
} }
#ifdef USE_OSD #ifdef USE_OSD
@ -427,7 +436,7 @@ void OpenGLGraphicsManager::updateScreen() {
g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f); g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, _osdAlpha / 100.0f);
// Draw the OSD texture. // Draw the OSD texture.
_osd->draw(0, 0, _outputScreenWidth, _outputScreenHeight); g_context.activePipeline->drawTexture(_osd->getGLTexture(), 0, 0, _outputScreenWidth, _outputScreenHeight);
// Reset color. // Reset color.
g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f); g_context.activePipeline->setColor(1.0f, 1.0f, 1.0f, 1.0f);

View file

@ -67,9 +67,12 @@ void FixedPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
GL_CALL(glColor4f(r, g, b, a)); GL_CALL(glColor4f(r, g, b, a));
} }
void FixedPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) { void FixedPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords)); texture.bind();
GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
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) { 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)); GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
} }
void ShaderPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) { void ShaderPipeline::drawTexture(const GLTexture &texture, const GLfloat *coordinates) {
GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords)); texture.bind();
GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
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) { void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {

View file

@ -24,6 +24,7 @@
#define BACKENDS_GRAPHICS_OPENGL_PIEPLINE_H #define BACKENDS_GRAPHICS_OPENGL_PIEPLINE_H
#include "backends/graphics/opengl/opengl-sys.h" #include "backends/graphics/opengl/opengl-sys.h"
#include "backends/graphics/opengl/texture.h"
namespace OpenGL { namespace OpenGL {
@ -87,13 +88,22 @@ public:
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) = 0; 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 texture Texture to use for drawing.
* @param texCoords The list of texture coordinates, 2 coordinates for * @param coordinates x1, y1, x2, y2 coordinates where to draw the texture.
* each vertex.
*/ */
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. * Set the projection matrix.
@ -113,7 +123,7 @@ public:
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a); 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); virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
}; };
@ -130,7 +140,7 @@ public:
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a); 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); virtual void setProjectionMatrix(const GLfloat *projectionMatrix);

View file

@ -95,7 +95,7 @@ void GLTexture::create() {
} }
} }
void GLTexture::bind() { void GLTexture::bind() const {
GL_CALL(glBindTexture(GL_TEXTURE_2D, _glTexture)); 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)); _userPixelData = _textureData.getSubArea(Common::Rect(width, height));
} }
void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) { void Texture::updateGLTexture() {
// 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() {
if (!isDirty()) { if (!isDirty()) {
return; return;
} }
@ -418,7 +391,7 @@ inline void doPaletteLookUp(PixelType *dst, const byte *src, uint width, uint he
} }
} // End of anonymous namespace } // End of anonymous namespace
void TextureCLUT8::updateTexture() { void TextureCLUT8::updateGLTexture() {
if (!isDirty()) { if (!isDirty()) {
return; return;
} }
@ -443,7 +416,7 @@ void TextureCLUT8::updateTexture() {
} }
// Do generic handling of updating the texture. // Do generic handling of updating the texture.
Texture::updateTexture(); Texture::updateGLTexture();
} }
#if !USE_FORCED_GL #if !USE_FORCED_GL
@ -502,7 +475,7 @@ void TextureRGB555::updateTexture() {
} }
// Do generic handling of updating the texture. // Do generic handling of updating the texture.
Texture::updateTexture(); Texture::updateGLTexture();
} }
#endif // !USE_FORCED_GL #endif // !USE_FORCED_GL
@ -582,33 +555,6 @@ void TextureCLUT8GPU::allocate(uint width, uint height) {
_clut8Vertices[7] = 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 { Graphics::PixelFormat TextureCLUT8GPU::getFormat() const {
return Graphics::PixelFormat::createFormatCLUT8(); return Graphics::PixelFormat::createFormatCLUT8();
} }
@ -633,7 +579,11 @@ void TextureCLUT8GPU::setPalette(uint start, uint colors, const byte *palData) {
_paletteDirty = true; _paletteDirty = true;
} }
void TextureCLUT8GPU::updateTextures() { const GLTexture &TextureCLUT8GPU::getGLTexture() const {
return *_target->getTexture();
}
void TextureCLUT8GPU::updateGLTexture() {
const bool needLookUp = Surface::isDirty() || _paletteDirty; const bool needLookUp = Surface::isDirty() || _paletteDirty;
// Update CLUT8 texture if necessary. // Update CLUT8 texture if necessary.
@ -674,14 +624,10 @@ void TextureCLUT8GPU::lookUpColors() {
// Set the palette texture. // Set the palette texture.
GL_CALL(glActiveTexture(GL_TEXTURE1)); GL_CALL(glActiveTexture(GL_TEXTURE1));
_paletteTexture.bind(); _paletteTexture.bind();
// Set the clut8 texture.
GL_CALL(glActiveTexture(GL_TEXTURE0)); GL_CALL(glActiveTexture(GL_TEXTURE0));
_clut8Texture.bind();
// Do color look up. // Do color look up.
g_context.activePipeline->setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords()); g_context.activePipeline->drawTexture(_clut8Texture, _clut8Vertices);
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
// Restore old state. // Restore old state.
g_context.activePipeline->setShader(oldShader); g_context.activePipeline->setShader(oldShader);

View file

@ -76,7 +76,7 @@ public:
/** /**
* Bind the texture to the active texture unit. * Bind the texture to the active texture unit.
*/ */
void bind(); void bind() const;
/** /**
* Sets the size of the texture in pixels. * Sets the size of the texture in pixels.
@ -182,8 +182,6 @@ public:
*/ */
void fill(uint32 color); void fill(uint32 color);
virtual void draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) = 0;
void flagDirty() { _allDirty = true; } void flagDirty() { _allDirty = true; }
virtual bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); } virtual bool isDirty() const { return _allDirty || !_dirtyArea.isEmpty(); }
@ -212,6 +210,16 @@ public:
*/ */
virtual void setColorKey(uint colorKey) {} virtual void setColorKey(uint colorKey) {}
virtual void setPalette(uint start, uint colors, const byte *palData) {} 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: protected:
void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); } void clearDirty() { _allDirty = false; _dirtyArea = Common::Rect(); }
@ -246,8 +254,6 @@ public:
virtual void allocate(uint width, uint height); 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 getWidth() const { return _userPixelData.w; }
virtual uint getHeight() const { return _userPixelData.h; } virtual uint getHeight() const { return _userPixelData.h; }
@ -259,11 +265,11 @@ public:
virtual Graphics::Surface *getSurface() { return &_userPixelData; } virtual Graphics::Surface *getSurface() { return &_userPixelData; }
virtual const Graphics::Surface *getSurface() const { return &_userPixelData; } virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
virtual void updateGLTexture();
virtual const GLTexture &getGLTexture() const { return _glTexture; }
protected: protected:
const Graphics::PixelFormat _format; const Graphics::PixelFormat _format;
virtual void updateTexture();
private: private:
GLTexture _glTexture; GLTexture _glTexture;
@ -288,9 +294,7 @@ public:
virtual Graphics::Surface *getSurface() { return &_clut8Data; } virtual Graphics::Surface *getSurface() { return &_clut8Data; }
virtual const Graphics::Surface *getSurface() const { return &_clut8Data; } virtual const Graphics::Surface *getSurface() const { return &_clut8Data; }
protected: virtual void updateGLTexture();
virtual void updateTexture();
private: private:
Graphics::Surface _clut8Data; Graphics::Surface _clut8Data;
byte *_palette; byte *_palette;
@ -309,9 +313,7 @@ public:
virtual Graphics::Surface *getSurface() { return &_rgb555Data; } virtual Graphics::Surface *getSurface() { return &_rgb555Data; }
virtual const Graphics::Surface *getSurface() const { return &_rgb555Data; } virtual const Graphics::Surface *getSurface() const { return &_rgb555Data; }
protected:
virtual void updateTexture(); virtual void updateTexture();
private: private:
Graphics::Surface _rgb555Data; Graphics::Surface _rgb555Data;
}; };
@ -333,8 +335,6 @@ public:
virtual void allocate(uint width, uint height); 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 bool isDirty() const { return _paletteDirty || Surface::isDirty(); }
virtual uint getWidth() const { return _userPixelData.w; } virtual uint getWidth() const { return _userPixelData.w; }
@ -350,13 +350,15 @@ public:
virtual Graphics::Surface *getSurface() { return &_userPixelData; } virtual Graphics::Surface *getSurface() { return &_userPixelData; }
virtual const Graphics::Surface *getSurface() const { return &_userPixelData; } virtual const Graphics::Surface *getSurface() const { return &_userPixelData; }
virtual void updateGLTexture();
virtual const GLTexture &getGLTexture() const;
static bool isSupportedByContext() { static bool isSupportedByContext() {
return g_context.shadersSupported return g_context.shadersSupported
&& g_context.multitextureSupported && g_context.multitextureSupported
&& g_context.framebufferObjectSupported; && g_context.framebufferObjectSupported;
} }
private: private:
void updateTextures();
void lookUpColors(); void lookUpColors();
GLTexture _clut8Texture; GLTexture _clut8Texture;