OPENGL: Make shader/framebuffer part of pipeline state.
This commit is contained in:
parent
0b46af2f0e
commit
0fe580d10c
8 changed files with 126 additions and 69 deletions
|
@ -43,24 +43,9 @@ void Context::reset() {
|
|||
#include "backends/graphics/opengl/opengl-func.h"
|
||||
#undef GL_FUNC_DEF
|
||||
|
||||
activeFramebuffer = nullptr;
|
||||
activePipeline = nullptr;
|
||||
}
|
||||
|
||||
Framebuffer *Context::setFramebuffer(Framebuffer *framebuffer) {
|
||||
Framebuffer *oldFramebuffer = activeFramebuffer;
|
||||
if (oldFramebuffer) {
|
||||
oldFramebuffer->deactivate();
|
||||
}
|
||||
|
||||
activeFramebuffer = framebuffer;
|
||||
if (activeFramebuffer) {
|
||||
activeFramebuffer->activate();
|
||||
}
|
||||
|
||||
return oldFramebuffer;
|
||||
}
|
||||
|
||||
Pipeline *Context::setPipeline(Pipeline *pipeline) {
|
||||
Pipeline *oldPipeline = activePipeline;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "backends/graphics/opengl/framebuffer.h"
|
||||
#include "backends/graphics/opengl/texture.h"
|
||||
#include "backends/graphics/opengl/pipeline.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
|
@ -34,6 +35,7 @@ void Framebuffer::activate() {
|
|||
_isActive = true;
|
||||
|
||||
applyViewport();
|
||||
applyProjectionMatrix();
|
||||
applyClearColor();
|
||||
applyBlendState();
|
||||
applyScissorTestState();
|
||||
|
@ -90,6 +92,10 @@ void Framebuffer::applyViewport() {
|
|||
GL_CALL(glViewport(_viewport[0], _viewport[1], _viewport[2], _viewport[3]));
|
||||
}
|
||||
|
||||
void Framebuffer::applyProjectionMatrix() {
|
||||
g_context.activePipeline->setProjectionMatrix(_projectionMatrix);
|
||||
}
|
||||
|
||||
void Framebuffer::applyClearColor() {
|
||||
GL_CALL(glClearColor(_clearColor[0], _clearColor[1], _clearColor[2], _clearColor[3]));
|
||||
}
|
||||
|
@ -159,6 +165,7 @@ void Backbuffer::setDimensions(uint width, uint height) {
|
|||
// Directly apply changes when we are active.
|
||||
if (isActive()) {
|
||||
applyViewport();
|
||||
applyProjectionMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,6 +251,7 @@ void TextureTarget::setSize(uint width, uint height) {
|
|||
// Directly apply changes when we are active.
|
||||
if (isActive()) {
|
||||
applyViewport();
|
||||
applyProjectionMatrix();
|
||||
}
|
||||
}
|
||||
#endif // !USE_FORCED_GLES
|
||||
|
|
|
@ -81,6 +81,7 @@ protected:
|
|||
void applyViewport();
|
||||
|
||||
GLfloat _projectionMatrix[4*4];
|
||||
void applyProjectionMatrix();
|
||||
private:
|
||||
bool _isActive;
|
||||
|
||||
|
|
|
@ -763,26 +763,6 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
|
|||
// Setup backbuffer size.
|
||||
_backBuffer.setDimensions(width, height);
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
if (!g_context.shadersSupported) {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES2
|
||||
GL_CALL(glMatrixMode(GL_PROJECTION));
|
||||
GL_CALL(glLoadMatrixf(_backBuffer.getProjectionMatrix()));
|
||||
|
||||
GL_CALL(glMatrixMode(GL_MODELVIEW));
|
||||
GL_CALL(glLoadIdentity());
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
} else {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES
|
||||
ShaderMan.query(ShaderManager::kDefault)->activate(_backBuffer.getProjectionMatrix());
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
}
|
||||
#endif
|
||||
|
||||
uint overlayWidth = width;
|
||||
uint overlayHeight = height;
|
||||
|
||||
|
@ -872,6 +852,14 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
|||
|
||||
g_context.setPipeline(_pipeline);
|
||||
|
||||
#if !USE_FORCED_GLES
|
||||
if (g_context.shadersSupported) {
|
||||
ShaderMan.notifyCreate();
|
||||
|
||||
g_context.activePipeline->setShader(ShaderMan.query(ShaderManager::kDefault));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Disable 3D properties.
|
||||
GL_CALL(glDisable(GL_CULL_FACE));
|
||||
GL_CALL(glDisable(GL_DEPTH_TEST));
|
||||
|
@ -890,7 +878,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
|||
// Setup scissor state accordingly.
|
||||
_backBuffer.enableScissorTest(!_overlayVisible);
|
||||
|
||||
g_context.setFramebuffer(&_backBuffer);
|
||||
g_context.activePipeline->setFramebuffer(&_backBuffer);
|
||||
|
||||
// Clear the whole screen for the first three frames to assure any
|
||||
// leftovers are cleared.
|
||||
|
@ -901,13 +889,6 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
|||
// code and that requires the same alignment too.
|
||||
GL_CALL(glPixelStorei(GL_PACK_ALIGNMENT, 4));
|
||||
|
||||
#if !USE_FORCED_GLES
|
||||
if (g_context.shadersSupported) {
|
||||
ShaderMan.notifyCreate();
|
||||
ShaderMan.query(ShaderManager::kDefault)->activate(_backBuffer.getProjectionMatrix());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Refresh the output screen dimensions if some are set up.
|
||||
if (_outputScreenWidth != 0 && _outputScreenHeight != 0) {
|
||||
setActualScreenSize(_outputScreenWidth, _outputScreenHeight);
|
||||
|
@ -963,9 +944,6 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
|
|||
}
|
||||
#endif
|
||||
|
||||
// Unset back buffer.
|
||||
g_context.setFramebuffer(nullptr);
|
||||
|
||||
// Destroy rendering pipeline.
|
||||
g_context.setPipeline(nullptr);
|
||||
delete _pipeline;
|
||||
|
|
|
@ -124,19 +124,6 @@ struct Context {
|
|||
#include "backends/graphics/opengl/opengl-func.h"
|
||||
#undef GL_FUNC_DEF
|
||||
|
||||
/** Currently active framebuffer. */
|
||||
Framebuffer *activeFramebuffer;
|
||||
|
||||
/**
|
||||
* Set new framebuffer.
|
||||
*
|
||||
* Client is responsible for any memory management related to framebuffers.
|
||||
*
|
||||
* @param framebuffer Framebuffer to activate.
|
||||
* @return Formerly active framebuffer.
|
||||
*/
|
||||
Framebuffer *setFramebuffer(Framebuffer *framebuffer);
|
||||
|
||||
//
|
||||
// Wrapper functionality to handle fixed-function pipelines and
|
||||
// programmable pipelines in the same fashion.
|
||||
|
|
|
@ -22,9 +22,29 @@
|
|||
|
||||
#include "backends/graphics/opengl/pipeline.h"
|
||||
#include "backends/graphics/opengl/shader.h"
|
||||
#include "backends/graphics/opengl/framebuffer.h"
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
Pipeline::Pipeline()
|
||||
: _activeFramebuffer(nullptr) {
|
||||
}
|
||||
|
||||
Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
|
||||
Framebuffer *oldFramebuffer = _activeFramebuffer;
|
||||
if (oldFramebuffer) {
|
||||
oldFramebuffer->deactivate();
|
||||
}
|
||||
|
||||
_activeFramebuffer = framebuffer;
|
||||
if (_activeFramebuffer) {
|
||||
_activeFramebuffer->activate();
|
||||
setProjectionMatrix(_activeFramebuffer->getProjectionMatrix());
|
||||
}
|
||||
|
||||
return oldFramebuffer;
|
||||
}
|
||||
|
||||
#if !USE_FORCED_GLES2
|
||||
void FixedPipeline::activate() {
|
||||
GL_CALL(glDisable(GL_LIGHTING));
|
||||
|
@ -51,9 +71,21 @@ void FixedPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *t
|
|||
GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texCoords));
|
||||
GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
|
||||
}
|
||||
|
||||
void FixedPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
|
||||
GL_CALL(glMatrixMode(GL_PROJECTION));
|
||||
GL_CALL(glLoadMatrixf(projectionMatrix));
|
||||
|
||||
GL_CALL(glMatrixMode(GL_MODELVIEW));
|
||||
GL_CALL(glLoadIdentity());
|
||||
}
|
||||
#endif // !USE_FORCED_GLES2
|
||||
|
||||
#if !USE_FORCED_GLES
|
||||
ShaderPipeline::ShaderPipeline()
|
||||
: _activeShader(nullptr) {
|
||||
}
|
||||
|
||||
void ShaderPipeline::activate() {
|
||||
GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
|
||||
GL_CALL(glEnableVertexAttribArray(kTexCoordAttribLocation));
|
||||
|
@ -63,6 +95,17 @@ void ShaderPipeline::activate() {
|
|||
}
|
||||
}
|
||||
|
||||
Shader *ShaderPipeline::setShader(Shader *shader) {
|
||||
Shader *oldShader = _activeShader;
|
||||
|
||||
_activeShader = shader;
|
||||
if (_activeShader && _activeFramebuffer) {
|
||||
_activeShader->activate(_activeFramebuffer->getProjectionMatrix());
|
||||
}
|
||||
|
||||
return oldShader;
|
||||
}
|
||||
|
||||
void ShaderPipeline::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||
GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
|
||||
}
|
||||
|
@ -71,6 +114,12 @@ void ShaderPipeline::setDrawCoordinates(const GLfloat *vertices, const GLfloat *
|
|||
GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texCoords));
|
||||
GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
|
||||
}
|
||||
|
||||
void ShaderPipeline::setProjectionMatrix(const GLfloat *projectionMatrix) {
|
||||
if (_activeShader) {
|
||||
_activeShader->activate(projectionMatrix);
|
||||
}
|
||||
}
|
||||
#endif // !USE_FORCED_GLES
|
||||
|
||||
} // End of namespace OpenGL
|
||||
|
|
|
@ -27,6 +27,11 @@
|
|||
|
||||
namespace OpenGL {
|
||||
|
||||
class Framebuffer;
|
||||
#if !USE_FORCED_GLES
|
||||
class Shader;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Interface for OpenGL pipeline functionality.
|
||||
*
|
||||
|
@ -35,6 +40,7 @@ namespace OpenGL {
|
|||
*/
|
||||
class Pipeline {
|
||||
public:
|
||||
Pipeline();
|
||||
virtual ~Pipeline() {}
|
||||
|
||||
/**
|
||||
|
@ -45,6 +51,31 @@ public:
|
|||
*/
|
||||
virtual void activate() = 0;
|
||||
|
||||
/**
|
||||
* Set framebuffer to render to.
|
||||
*
|
||||
* Client is responsible for any memory management related to framebuffer.
|
||||
*
|
||||
* @param framebuffer Framebuffer to activate.
|
||||
* @return Formerly active framebuffer.
|
||||
*/
|
||||
Framebuffer *setFramebuffer(Framebuffer *framebuffer);
|
||||
|
||||
#if !USE_FORCED_GLES
|
||||
/**
|
||||
* Set shader program.
|
||||
*
|
||||
* Not all pipelines support shader programs. This is method exits at this
|
||||
* place for convenience only.
|
||||
*
|
||||
* Client is responsible for any memory management related to shader.
|
||||
*
|
||||
* @param shader Shader program to activate.
|
||||
* @return Formerly active shader program.
|
||||
*/
|
||||
virtual Shader *setShader(Shader *shader) { return nullptr; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set modulation color.
|
||||
*
|
||||
|
@ -63,6 +94,16 @@ public:
|
|||
* each vertex.
|
||||
*/
|
||||
virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords) = 0;
|
||||
|
||||
/**
|
||||
* Set the projection matrix.
|
||||
*
|
||||
* This is intended to be only ever be used by Framebuffer subclasses.
|
||||
*/
|
||||
virtual void setProjectionMatrix(const GLfloat *projectionMatrix) = 0;
|
||||
|
||||
protected:
|
||||
Framebuffer *_activeFramebuffer;
|
||||
};
|
||||
|
||||
#if !USE_FORCED_GLES2
|
||||
|
@ -73,17 +114,28 @@ public:
|
|||
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
|
||||
virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
|
||||
|
||||
virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
|
||||
};
|
||||
#endif // !USE_FORCED_GLES2
|
||||
|
||||
#if !USE_FORCED_GLES
|
||||
class ShaderPipeline : public Pipeline {
|
||||
public:
|
||||
ShaderPipeline();
|
||||
|
||||
virtual void activate();
|
||||
|
||||
virtual Shader *setShader(Shader *shader);
|
||||
|
||||
virtual void setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||
|
||||
virtual void setDrawCoordinates(const GLfloat *vertices, const GLfloat *texCoords);
|
||||
|
||||
virtual void setProjectionMatrix(const GLfloat *projectionMatrix);
|
||||
|
||||
private:
|
||||
Shader *_activeShader;
|
||||
};
|
||||
#endif // !USE_FORCED_GLES
|
||||
|
||||
|
|
|
@ -657,7 +657,7 @@ void TextureCLUT8GPU::updateTextures() {
|
|||
_paletteDirty = false;
|
||||
}
|
||||
|
||||
// In case any data changed, do color look up and save result in _glTexture.
|
||||
// In case any data changed, do color look up and store result in _target.
|
||||
if (needLookUp) {
|
||||
lookUpColors();
|
||||
}
|
||||
|
@ -665,10 +665,11 @@ void TextureCLUT8GPU::updateTextures() {
|
|||
|
||||
void TextureCLUT8GPU::lookUpColors() {
|
||||
// Save old state.
|
||||
GLint oldProgram = 0;
|
||||
GL_CALL(glGetIntegerv(GL_CURRENT_PROGRAM, &oldProgram));
|
||||
Framebuffer *oldFramebuffer = g_context.activePipeline->setFramebuffer(_target);
|
||||
|
||||
Framebuffer *oldFramebuffer = g_context.setFramebuffer(_target);
|
||||
Shader *lookUpShader = ShaderMan.query(ShaderManager::kCLUT8LookUp);
|
||||
Shader *oldShader = g_context.activePipeline->setShader(lookUpShader);
|
||||
lookUpShader->setUniformI(_paletteLocation, 1);
|
||||
|
||||
// Set the palette texture.
|
||||
GL_CALL(glActiveTexture(GL_TEXTURE1));
|
||||
|
@ -679,16 +680,12 @@ void TextureCLUT8GPU::lookUpColors() {
|
|||
_clut8Texture.bind();
|
||||
|
||||
// Do color look up.
|
||||
Shader *lookUpShader = ShaderMan.query(ShaderManager::kCLUT8LookUp);
|
||||
lookUpShader->activate(_target->getProjectionMatrix());
|
||||
lookUpShader->setUniformI(_paletteLocation, 1);
|
||||
g_context.activePipeline->setDrawCoordinates(_clut8Vertices, _clut8Texture.getTexCoords());
|
||||
GL_CALL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
|
||||
|
||||
// Restore old state.
|
||||
g_context.setFramebuffer(oldFramebuffer);
|
||||
|
||||
GL_CALL(glUseProgram(oldProgram));
|
||||
g_context.activePipeline->setShader(oldShader);
|
||||
g_context.activePipeline->setFramebuffer(oldFramebuffer);
|
||||
}
|
||||
#endif // !USE_FORCED_GLES
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue