mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
reimplement postprocessing and fix one shader as example
This commit is contained in:
parent
5dd502df3b
commit
800a58f01c
@ -1,7 +1,9 @@
|
|||||||
uniform samplerRECT samp0 : register(s0);
|
uniform sampler2D samp9;
|
||||||
|
|
||||||
void main(out float4 ocol0 : COLOR0, in float2 uv0 : TEXCOORD0)
|
out vec4 ocol0;
|
||||||
|
in vec2 uv0;
|
||||||
|
|
||||||
|
void main()
|
||||||
{
|
{
|
||||||
float4 c0 = texRECT(samp0, uv0).rgba;
|
ocol0 = vec4(1.0, 1.0, 1.0, 1.0) - texture(samp9, uv0);
|
||||||
ocol0 = float4(1.0, 1.0, 1.0, 1.0) - c0;
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "GLUtil.h"
|
#include "GLUtil.h"
|
||||||
#include "PostProcessing.h"
|
#include "PostProcessing.h"
|
||||||
#include "ProgramShaderCache.h"
|
#include "ProgramShaderCache.h"
|
||||||
|
#include "FramebufferManager.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
@ -30,15 +31,67 @@ namespace PostProcessing
|
|||||||
|
|
||||||
static std::string s_currentShader;
|
static std::string s_currentShader;
|
||||||
static SHADER s_shader;
|
static SHADER s_shader;
|
||||||
|
static bool s_enable;
|
||||||
|
|
||||||
|
static u32 s_width;
|
||||||
|
static u32 s_height;
|
||||||
|
static GLuint s_fbo;
|
||||||
|
static GLuint s_texture;
|
||||||
|
static GLuint s_vao;
|
||||||
|
static GLuint s_vbo;
|
||||||
|
|
||||||
|
static char* s_vertex_shader =
|
||||||
|
"in vec2 rawpos;\n"
|
||||||
|
"in vec2 tex0;\n"
|
||||||
|
"out vec2 uv0;\n"
|
||||||
|
"void main(void) {\n"
|
||||||
|
" gl_Position = vec4(rawpos,0,1);\n"
|
||||||
|
" uv0 = tex0;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
s_currentShader = "";
|
s_currentShader = "";
|
||||||
|
s_enable = 0;
|
||||||
|
s_width = 0;
|
||||||
|
s_height = 0;
|
||||||
|
|
||||||
|
glGenFramebuffers(1, &s_fbo);
|
||||||
|
glGenTextures(1, &s_texture);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, s_texture);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); // disable mipmaps
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, s_fbo);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s_texture, 0);
|
||||||
|
FramebufferManager::SetFramebuffer(0);
|
||||||
|
|
||||||
|
glGenBuffers(1, &s_vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, s_vbo);
|
||||||
|
GLfloat vertices[] = {
|
||||||
|
-1.f, -1.f, 0.f, 0.f,
|
||||||
|
-1.f, 1.f, 0.f, 1.f,
|
||||||
|
1.f, -1.f, 1.f, 0.f,
|
||||||
|
1.f, 1.f, 1.f, 1.f
|
||||||
|
};
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &s_vao);
|
||||||
|
glBindVertexArray( s_vao );
|
||||||
|
glEnableVertexAttribArray(SHADER_POSITION_ATTRIB);
|
||||||
|
glVertexAttribPointer(SHADER_POSITION_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, NULL);
|
||||||
|
glEnableVertexAttribArray(SHADER_TEXTURE0_ATTRIB);
|
||||||
|
glVertexAttribPointer(SHADER_TEXTURE0_ATTRIB, 2, GL_FLOAT, 0, sizeof(GLfloat)*4, (GLfloat*)NULL+2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
s_shader.Destroy();
|
s_shader.Destroy();
|
||||||
|
|
||||||
|
glDeleteFramebuffers(1, &s_vbo);
|
||||||
|
glDeleteTextures(1, &s_texture);
|
||||||
|
|
||||||
|
glDeleteBuffers(1, &s_vbo);
|
||||||
|
glDeleteVertexArrays(1, &s_vao);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReloadShader()
|
void ReloadShader()
|
||||||
@ -46,45 +99,77 @@ void ReloadShader()
|
|||||||
s_currentShader = "";
|
s_currentShader = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ApplyShader()
|
void BindTargetFramebuffer ()
|
||||||
{
|
{
|
||||||
if (s_currentShader != File::GetUserPath(D_SHADERS_IDX) + g_ActiveConfig.sPostProcessingShader + ".txt")
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_enable ? s_fbo : 0);
|
||||||
{
|
}
|
||||||
// Set immediately to prevent endless recompiles on failure.
|
|
||||||
if (!g_ActiveConfig.sPostProcessingShader.empty())
|
|
||||||
s_currentShader = File::GetUserPath(D_SHADERS_IDX) + g_ActiveConfig.sPostProcessingShader + ".txt";
|
|
||||||
else
|
|
||||||
s_currentShader.clear();
|
|
||||||
|
|
||||||
s_shader.Destroy();
|
void BlitToScreen()
|
||||||
|
{
|
||||||
|
if(!s_enable) return;
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
|
glViewport(0, 0, s_width, s_height);
|
||||||
|
|
||||||
|
glBindVertexArray(s_vao);
|
||||||
|
s_shader.Bind();
|
||||||
|
glActiveTexture(GL_TEXTURE0+9);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, s_texture);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
|
/* glBindFramebuffer(GL_READ_FRAMEBUFFER, s_fbo);
|
||||||
|
|
||||||
|
glBlitFramebuffer(rc.left, rc.bottom, rc.right, rc.top,
|
||||||
|
rc.left, rc.bottom, rc.right, rc.top,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);*/
|
||||||
|
}
|
||||||
|
|
||||||
if (!s_currentShader.empty())
|
void Update ( u32 width, u32 height )
|
||||||
{
|
{
|
||||||
std::string code;
|
ApplyShader();
|
||||||
if (File::ReadFileToString(true, s_currentShader.c_str(), code))
|
|
||||||
{
|
|
||||||
//if (!ProgramShaderCache::CompileShader(s_shader, "#version130\n...", code.c_str()))
|
|
||||||
//{
|
|
||||||
// ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERROR_LOG(VIDEO, "Failed to load post-processing shader %s - does not exist?", s_currentShader.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Convert PP shaders to GLSL
|
if(s_enable && (width != s_width || height != s_height)) {
|
||||||
if (s_shader.glprogid != 0)
|
s_width = width;
|
||||||
{
|
s_height = height;
|
||||||
s_shader.Bind();
|
|
||||||
return true;
|
// alloc texture for framebuffer
|
||||||
|
glActiveTexture(GL_TEXTURE0+9);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, s_texture);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
return false;
|
void ApplyShader()
|
||||||
|
{
|
||||||
|
// shader didn't changed
|
||||||
|
if (s_currentShader == g_ActiveConfig.sPostProcessingShader) return;
|
||||||
|
s_currentShader = g_ActiveConfig.sPostProcessingShader;
|
||||||
|
s_enable = false;
|
||||||
|
s_shader.Destroy();
|
||||||
|
|
||||||
|
// shader disabled
|
||||||
|
if (g_ActiveConfig.sPostProcessingShader == "") return;
|
||||||
|
|
||||||
|
// so need to compile shader
|
||||||
|
|
||||||
|
// loading shader code
|
||||||
|
std::string code;
|
||||||
|
std::string path = File::GetUserPath(D_SHADERS_IDX) + g_ActiveConfig.sPostProcessingShader + ".txt";
|
||||||
|
if(!File::ReadFileToString(true, path.c_str(), code)) {
|
||||||
|
ERROR_LOG(VIDEO, "post-processing shader not found: %s", path.c_str());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// and compile it
|
||||||
|
if (!ProgramShaderCache::CompileShader(s_shader, s_vertex_shader, code.c_str())) {
|
||||||
|
ERROR_LOG(VIDEO, "Failed to compile post-processing shader %s", s_currentShader.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// successful
|
||||||
|
s_enable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -30,9 +30,13 @@ namespace PostProcessing
|
|||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
|
void BindTargetFramebuffer();
|
||||||
|
void BlitToScreen();
|
||||||
|
void Update(u32 width, u32 height);
|
||||||
|
|
||||||
void ReloadShader();
|
void ReloadShader();
|
||||||
// Returns false if no shader was applied.
|
|
||||||
bool ApplyShader();
|
void ApplyShader();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -996,6 +996,7 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
|
|
||||||
ResetAPIState();
|
ResetAPIState();
|
||||||
|
|
||||||
|
PostProcessing::Update(s_backbuffer_width, s_backbuffer_height);
|
||||||
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
|
||||||
TargetRectangle flipped_trc = GetTargetRectangle();
|
TargetRectangle flipped_trc = GetTargetRectangle();
|
||||||
|
|
||||||
@ -1003,31 +1004,17 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
int tmp = flipped_trc.top;
|
int tmp = flipped_trc.top;
|
||||||
flipped_trc.top = flipped_trc.bottom;
|
flipped_trc.top = flipped_trc.bottom;
|
||||||
flipped_trc.bottom = tmp;
|
flipped_trc.bottom = tmp;
|
||||||
|
|
||||||
// Textured triangles are necessary because of post-processing shaders
|
|
||||||
|
|
||||||
// Disable all other stages
|
|
||||||
for (int i = 0; i < 8; ++i)
|
|
||||||
OGL::TextureCache::DisableStage(i);
|
|
||||||
|
|
||||||
// Update GLViewPort
|
|
||||||
glViewport(flipped_trc.left, flipped_trc.bottom, flipped_trc.GetWidth(), flipped_trc.GetHeight());
|
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
// We must call ApplyShader here even if no post proc is selected - it takes
|
|
||||||
// care of disabling it in that case. It returns false in case of no post processing.
|
|
||||||
//bool applyShader = PostProcessing::ApplyShader();
|
|
||||||
// degasus: disabled for blitting
|
|
||||||
|
|
||||||
// Copy the framebuffer to screen.
|
// Copy the framebuffer to screen.
|
||||||
|
|
||||||
const XFBSourceBase* xfbSource = NULL;
|
const XFBSourceBase* xfbSource = NULL;
|
||||||
|
|
||||||
if(g_ActiveConfig.bUseXFB)
|
if(g_ActiveConfig.bUseXFB)
|
||||||
{
|
{
|
||||||
// Render to the real buffer now.
|
// Render to the real/postprocessing buffer now.
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // switch to the window backbuffer
|
PostProcessing::BindTargetFramebuffer();
|
||||||
|
|
||||||
// draw each xfb source
|
// draw each xfb source
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetXFBFramebuffer());
|
||||||
@ -1085,8 +1072,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
// for msaa mode, we must resolve the efb content to non-msaa
|
// for msaa mode, we must resolve the efb content to non-msaa
|
||||||
FramebufferManager::ResolveAndGetRenderTarget(rc);
|
FramebufferManager::ResolveAndGetRenderTarget(rc);
|
||||||
|
|
||||||
// Render to the real buffer now. (resolve have changed this in msaa mode)
|
// Render to the real/postprocessing buffer now. (resolve have changed this in msaa mode)
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
PostProcessing::BindTargetFramebuffer();
|
||||||
|
|
||||||
// always the non-msaa fbo
|
// always the non-msaa fbo
|
||||||
GLuint fb = s_MSAASamples>1?FramebufferManager::GetResolvedFramebuffer():FramebufferManager::GetEFBFramebuffer();
|
GLuint fb = s_MSAASamples>1?FramebufferManager::GetResolvedFramebuffer():FramebufferManager::GetEFBFramebuffer();
|
||||||
@ -1096,6 +1083,8 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons
|
|||||||
flipped_trc.left, flipped_trc.bottom, flipped_trc.right, flipped_trc.top,
|
flipped_trc.left, flipped_trc.bottom, flipped_trc.right, flipped_trc.top,
|
||||||
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PostProcessing::BlitToScreen();
|
||||||
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
@ -199,9 +199,9 @@ void VideoBackend::Video_Prepare()
|
|||||||
VertexShaderManager::Init();
|
VertexShaderManager::Init();
|
||||||
PixelShaderManager::Init();
|
PixelShaderManager::Init();
|
||||||
ProgramShaderCache::Init();
|
ProgramShaderCache::Init();
|
||||||
|
PostProcessing::Init();
|
||||||
g_texture_cache = new TextureCache();
|
g_texture_cache = new TextureCache();
|
||||||
g_sampler_cache = new SamplerCache();
|
g_sampler_cache = new SamplerCache();
|
||||||
PostProcessing::Init();
|
|
||||||
Renderer::Init();
|
Renderer::Init();
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
VertexLoaderManager::Init();
|
VertexLoaderManager::Init();
|
||||||
@ -231,7 +231,6 @@ void VideoBackend::Video_Cleanup() {
|
|||||||
DLCache::Shutdown();
|
DLCache::Shutdown();
|
||||||
#endif
|
#endif
|
||||||
Fifo_Shutdown();
|
Fifo_Shutdown();
|
||||||
PostProcessing::Shutdown();
|
|
||||||
|
|
||||||
// The following calls are NOT Thread Safe
|
// The following calls are NOT Thread Safe
|
||||||
// And need to be called from the video thread
|
// And need to be called from the video thread
|
||||||
@ -242,6 +241,7 @@ void VideoBackend::Video_Cleanup() {
|
|||||||
g_sampler_cache = NULL;
|
g_sampler_cache = NULL;
|
||||||
delete g_texture_cache;
|
delete g_texture_cache;
|
||||||
g_texture_cache = NULL;
|
g_texture_cache = NULL;
|
||||||
|
PostProcessing::Shutdown();
|
||||||
ProgramShaderCache::Shutdown();
|
ProgramShaderCache::Shutdown();
|
||||||
VertexShaderManager::Shutdown();
|
VertexShaderManager::Shutdown();
|
||||||
PixelShaderManager::Shutdown();
|
PixelShaderManager::Shutdown();
|
||||||
|
Loading…
Reference in New Issue
Block a user