From b17c035642cc33ee614046be011bf8ad9f9db95d Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 6 Jan 2016 16:52:03 +0100 Subject: OPENGL: Implement texture drawing in Pipeline instead of Surface. --- backends/graphics/opengl/opengl-graphics.cpp | 21 +++++--- backends/graphics/opengl/pipeline.cpp | 18 ++++--- backends/graphics/opengl/pipeline.h | 24 ++++++--- backends/graphics/opengl/texture.cpp | 76 ++++------------------------ backends/graphics/opengl/texture.h | 32 ++++++------ 5 files changed, 72 insertions(+), 99 deletions(-) (limited to 'backends') diff --git a/backends/graphics/opengl/opengl-graphics.cpp b/backends/graphics/opengl/opengl-graphics.cpp index e32753ee3e..a685f34bbf 100644 --- a/backends/graphics/opengl/opengl-graphics.cpp +++ b/backends/graphics/opengl/opengl-graphics.cpp @@ -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,9 +409,10 @@ void OpenGLGraphicsManager::updateScreen() { // visible. const GLfloat cursorOffset = _overlayVisible ? 0 : shakeOffset; - _cursor->draw(_cursorDisplayX - _cursorHotspotXScaled, - _cursorDisplayY - _cursorHotspotYScaled + cursorOffset, - _cursorWidthScaled, _cursorHeightScaled); + g_context.activePipeline->drawTexture(_cursor->getGLTexture(), + _cursorDisplayX - _cursorHotspotXScaled, + _cursorDisplayY - _cursorHotspotYScaled + cursorOffset, + _cursorWidthScaled, _cursorHeightScaled); } #ifdef USE_OSD @@ -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); diff --git a/backends/graphics/opengl/pipeline.cpp b/backends/graphics/opengl/pipeline.cpp index 500597cc3d..9ac3fe44de 100644 --- a/backends/graphics/opengl/pipeline.cpp +++ b/backends/graphics/opengl/pipeline.cpp @@ -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) { diff --git a/backends/graphics/opengl/pipeline.h b/backends/graphics/opengl/pipeline.h index d101a99d9b..5ec52f2f28 100644 --- a/backends/graphics/opengl/pipeline.h +++ b/backends/graphics/opengl/pipeline.h @@ -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); diff --git a/backends/graphics/opengl/texture.cpp b/backends/graphics/opengl/texture.cpp index 05b7ac1896..8b38f85e9f 100644 --- a/backends/graphics/opengl/texture.cpp +++ b/backends/graphics/opengl/texture.cpp @@ -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); diff --git a/backends/graphics/opengl/texture.h b/backends/graphics/opengl/texture.h index df9893fa70..847c76db88 100644 --- a/backends/graphics/opengl/texture.h +++ b/backends/graphics/opengl/texture.h @@ -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; -- cgit v1.2.3