1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
|
// Copyright 2013 Dolphin Emulator Project
// Licensed under GPLv2
// Refer to the license.txt file included.
#include "Common/CommonPaths.h"
#include "Common/FileUtil.h"
#include "VideoBackends/OGL/FramebufferManager.h"
#include "VideoBackends/OGL/GLUtil.h"
#include "VideoBackends/OGL/PostProcessing.h"
#include "VideoBackends/OGL/ProgramShaderCache.h"
#include "VideoCommon/VideoCommon.h"
#include "VideoCommon/VideoConfig.h"
namespace OGL
{
namespace PostProcessing
{
static std::string s_currentShader;
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_uniform_resolution;
static char s_vertex_shader[] =
"out vec2 uv0;\n"
"void main(void) {\n"
" vec2 rawpos = vec2(gl_VertexID&1, gl_VertexID&2);\n"
" gl_Position = vec4(rawpos*2.0-1.0, 0.0, 1.0);\n"
" uv0 = rawpos;\n"
"}\n";
void Init()
{
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
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glBindFramebuffer(GL_FRAMEBUFFER, s_fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, s_texture, 0);
FramebufferManager::SetFramebuffer(0);
}
void Shutdown()
{
s_shader.Destroy();
glDeleteFramebuffers(1, &s_fbo);
glDeleteTextures(1, &s_texture);
}
void ReloadShader()
{
s_currentShader = "";
}
void BindTargetFramebuffer ()
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, s_enable ? s_fbo : 0);
}
void BlitToScreen()
{
if(!s_enable) return;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glViewport(0, 0, s_width, s_height);
s_shader.Bind();
glUniform4f(s_uniform_resolution, (float)s_width, (float)s_height, 1.0f/(float)s_width, 1.0f/(float)s_height);
glActiveTexture(GL_TEXTURE0+9);
glBindTexture(GL_TEXTURE_2D, s_texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
/* 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);*/
}
void Update ( u32 width, u32 height )
{
ApplyShader();
if(s_enable && (width != s_width || height != s_height)) {
s_width = width;
s_height = height;
// alloc texture for framebuffer
glActiveTexture(GL_TEXTURE0+9);
glBindTexture(GL_TEXTURE_2D, s_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
}
}
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 + ".glsl";
if (!File::Exists(path))
{
// Fallback to shared user dir
path = File::GetSysDirectory() + SHADERS_DIR DIR_SEP + g_ActiveConfig.sPostProcessingShader + ".glsl";
}
if(!File::ReadFileToString(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;
}
// read uniform locations
s_uniform_resolution = glGetUniformLocation(s_shader.glprogid, "resolution");
// successful
s_enable = true;
}
} // namespace
} // namespace OGL
|