glsl framebuffer_fetch extension check at runtime
This commit is contained in:
@@ -63,6 +63,13 @@
|
|||||||
" return fract(sin(sn) * c);\n"\
|
" return fract(sin(sn) * c);\n"\
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
|
#define SHADER_EXT_FB_FETCH \
|
||||||
|
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"\
|
||||||
|
" #extension GL_EXT_shader_framebuffer_fetch : enable\n"\
|
||||||
|
"#elif defined(GL_ARM_shader_framebuffer_fetch)\n"\
|
||||||
|
" #extension GL_ARM_shader_framebuffer_fetch : enable\n"\
|
||||||
|
"#endif\n"
|
||||||
|
|
||||||
void App::initShaders()
|
void App::initShaders()
|
||||||
{
|
{
|
||||||
static const char* shader_v =
|
static const char* shader_v =
|
||||||
@@ -85,9 +92,7 @@ void App::initShaders()
|
|||||||
"}\n";
|
"}\n";
|
||||||
static const char* shader_blend_f =
|
static const char* shader_blend_f =
|
||||||
SHADER_VERSION
|
SHADER_VERSION
|
||||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
SHADER_EXT_FB_FETCH
|
||||||
" #extension GL_EXT_shader_framebuffer_fetch : enable\n"
|
|
||||||
"#endif\n"
|
|
||||||
"uniform sampler2D tex;\n"
|
"uniform sampler2D tex;\n"
|
||||||
"uniform sampler2D tex_alpha;\n"
|
"uniform sampler2D tex_alpha;\n"
|
||||||
"uniform sampler2D tex_bg;\n"
|
"uniform sampler2D tex_bg;\n"
|
||||||
@@ -103,6 +108,8 @@ void App::initShaders()
|
|||||||
"void main() {\n"
|
"void main() {\n"
|
||||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
||||||
" highp vec4 bg = frag;\n"
|
" highp vec4 bg = frag;\n"
|
||||||
|
"#elif defined(GL_ARM_shader_framebuffer_fetch)\n"
|
||||||
|
" highp vec4 bg = gl_LastFragColorARM;\n"
|
||||||
"#else\n"
|
"#else\n"
|
||||||
" mediump vec4 bg = texture(tex_bg, uv);\n"
|
" mediump vec4 bg = texture(tex_bg, uv);\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
@@ -357,9 +364,7 @@ void App::initShaders()
|
|||||||
"}\n";
|
"}\n";
|
||||||
static const char* shader_stroke_f =
|
static const char* shader_stroke_f =
|
||||||
SHADER_VERSION
|
SHADER_VERSION
|
||||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
SHADER_EXT_FB_FETCH
|
||||||
" #extension GL_EXT_shader_framebuffer_fetch : enable\n"
|
|
||||||
"#endif\n"
|
|
||||||
"uniform mediump sampler2D tex;\n"
|
"uniform mediump sampler2D tex;\n"
|
||||||
"uniform mediump sampler2D tex_bg;\n"
|
"uniform mediump sampler2D tex_bg;\n"
|
||||||
"uniform mediump sampler2D tex_stencil;\n"
|
"uniform mediump sampler2D tex_stencil;\n"
|
||||||
@@ -388,6 +393,8 @@ void App::initShaders()
|
|||||||
" mediump vec4 fg = vec4(col.rgb, brush_alpha * stencil);\n"
|
" mediump vec4 fg = vec4(col.rgb, brush_alpha * stencil);\n"
|
||||||
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
"#if defined(GL_EXT_shader_framebuffer_fetch)\n"
|
||||||
" mediump vec4 bg = frag;\n"
|
" mediump vec4 bg = frag;\n"
|
||||||
|
"#elif defined(GL_ARM_shader_framebuffer_fetch)\n"
|
||||||
|
" mediump vec4 bg = gl_LastFragColorARM;\n"
|
||||||
"#else\n"
|
"#else\n"
|
||||||
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||||
"#endif\n"
|
"#endif\n"
|
||||||
@@ -592,6 +599,18 @@ void App::initShaders()
|
|||||||
" }\n"
|
" }\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
|
GLint n_exts;
|
||||||
|
glGetIntegerv(GL_NUM_EXTENSIONS, &n_exts);
|
||||||
|
for (int i = 0; i < n_exts; i++)
|
||||||
|
{
|
||||||
|
std::string ext = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
||||||
|
if (ext.find("shader_framebuffer_fetch") != std::string::npos)
|
||||||
|
{
|
||||||
|
ShaderManager::ext_framebuffer_fetch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG("Shader Extension shader_framebuffer_fetch: %s", ShaderManager::ext_framebuffer_fetch ? "enabled" : "disabled");
|
||||||
|
|
||||||
LOG("initializing shaders");
|
LOG("initializing shaders");
|
||||||
if (!ShaderManager::create(kShader::Texture, shader_v, shader_f))
|
if (!ShaderManager::create(kShader::Texture, shader_v, shader_f))
|
||||||
|
|||||||
@@ -394,9 +394,8 @@ void Canvas::stroke_draw()
|
|||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
ShaderManager::use(kShader::Stroke);
|
ShaderManager::use(kShader::Stroke);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
|
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
|
||||||
#ifndef __IOS__
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg
|
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg
|
||||||
#endif
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexStencil, 2); // stencil
|
ShaderManager::u_int(kShaderUniform::TexStencil, 2); // stencil
|
||||||
ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer
|
ShaderManager::u_int(kShaderUniform::TexMix, 3); // mixer
|
||||||
//ShaderManager::u_int(kShaderUniform::TexMixA, 4); // mixer
|
//ShaderManager::u_int(kShaderUniform::TexMixA, 4); // mixer
|
||||||
@@ -549,8 +548,11 @@ void Canvas::stroke_draw()
|
|||||||
|
|
||||||
m_tmp[i].bindFramebuffer();
|
m_tmp[i].bindFramebuffer();
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
m_tex[i].bind(); // bg, copy of framebuffer (copied before drawing)
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_tex[i].bind(); // bg, copy of framebuffer (copied before drawing)
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec2 bb_min(m_width, m_height);
|
glm::vec2 bb_min(m_width, m_height);
|
||||||
glm::vec2 bb_max(0, 0);
|
glm::vec2 bb_max(0, 0);
|
||||||
@@ -564,12 +566,11 @@ void Canvas::stroke_draw()
|
|||||||
glm::vec2 pad(1);
|
glm::vec2 pad(1);
|
||||||
glm::ivec2 tex_pos = glm::clamp(glm::floor(bb_min) - pad , { 0, 0 }, { m_width, m_height });
|
glm::ivec2 tex_pos = glm::clamp(glm::floor(bb_min) - pad , { 0, 0 }, { m_width, m_height });
|
||||||
glm::ivec2 tex_sz = glm::clamp(glm::ceil(bb_sz ) + pad*2.f, { 0, 0 }, (glm::vec2)(glm::ivec2(m_width, m_height) - tex_pos));
|
glm::ivec2 tex_sz = glm::clamp(glm::ceil(bb_sz ) + pad*2.f, { 0, 0 }, (glm::vec2)(glm::ivec2(m_width, m_height) - tex_pos));
|
||||||
#ifndef __IOS__
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
|
{
|
||||||
tex_pos.x, tex_pos.y,
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, tex_pos.x, tex_pos.y,
|
||||||
tex_pos.x, tex_pos.y,
|
tex_pos.x, tex_pos.y, tex_sz.x, tex_sz.y);
|
||||||
tex_sz.x, tex_sz.y);
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
m_dirty_box[i] = glm::vec4(
|
m_dirty_box[i] = glm::vec4(
|
||||||
glm::min(xy(m_dirty_box[i]), (glm::vec2)tex_pos),
|
glm::min(xy(m_dirty_box[i]), (glm::vec2)tex_pos),
|
||||||
@@ -630,8 +631,11 @@ void Canvas::stroke_draw()
|
|||||||
m_brush_shape.draw_stroke();
|
m_brush_shape.draw_stroke();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
m_tex[i].unbind();
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_tex[i].unbind();
|
||||||
|
}
|
||||||
|
|
||||||
m_tmp[i].unbindFramebuffer();
|
m_tmp[i].unbindFramebuffer();
|
||||||
}
|
}
|
||||||
@@ -1307,26 +1311,32 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
ShaderManager::use(kShader::TextureBlend);
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
|
|
||||||
m_tmp[i].bindFramebuffer();
|
m_tmp[i].bindFramebuffer();
|
||||||
// clear transparent not to mess with blending modes
|
// clear transparent not to mess with blending modes
|
||||||
m_tmp[i].clear({ 1, 1, 1, 0 });
|
m_tmp[i].clear({ 1, 1, 1, 0 });
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
face.bind();
|
{
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
face.bind();
|
||||||
|
m_sampler_bg.bind(2);
|
||||||
|
}
|
||||||
m_sampler_bg.bind(0); // nearest
|
m_sampler_bg.bind(0); // nearest
|
||||||
m_sampler_mask.bind(1); // linear
|
m_sampler_mask.bind(1); // linear
|
||||||
m_sampler_bg.bind(2);
|
|
||||||
for (auto layer_index : m_order)
|
for (auto layer_index : m_order)
|
||||||
{
|
{
|
||||||
if (!m_layers[layer_index].m_visible ||
|
if (!m_layers[layer_index].m_visible ||
|
||||||
m_layers[layer_index].m_opacity == 0.f ||
|
m_layers[layer_index].m_opacity == 0.f ||
|
||||||
!m_layers[layer_index].m_dirty_face[i])
|
!m_layers[layer_index].m_dirty_face[i])
|
||||||
continue;
|
continue;
|
||||||
glActiveTexture(GL_TEXTURE2);
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||||
|
}
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index].m_blend_mode);
|
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index].m_blend_mode);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
@@ -1338,8 +1348,12 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_layers[layer_index].m_rtt[i].unbindTexture();
|
m_layers[layer_index].m_rtt[i].unbindTexture();
|
||||||
}
|
}
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
face.unbind();
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
face.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
// now blend with the background
|
// now blend with the background
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
@@ -2131,21 +2145,27 @@ Image Canvas::thumbnail_generate(int w, int h)
|
|||||||
ShaderManager::use(kShader::TextureBlend);
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
||||||
glActiveTexture(GL_TEXTURE2);
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
blendtex.bind();
|
{
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
blendtex.bind();
|
||||||
|
m_sampler_bg.bind(2);
|
||||||
|
}
|
||||||
m_sampler_bg.bind(0); // nearest
|
m_sampler_bg.bind(0); // nearest
|
||||||
m_sampler_mask.bind(1); // linear
|
m_sampler_mask.bind(1); // linear
|
||||||
m_sampler_bg.bind(2);
|
|
||||||
for (auto layer_index : m_order)
|
for (auto layer_index : m_order)
|
||||||
{
|
{
|
||||||
if (!m_layers[layer_index].m_visible ||
|
if (!m_layers[layer_index].m_visible ||
|
||||||
m_layers[layer_index].m_opacity == 0.f ||
|
m_layers[layer_index].m_opacity == 0.f ||
|
||||||
!m_layers[layer_index].m_dirty_face[i])
|
!m_layers[layer_index].m_dirty_face[i])
|
||||||
continue;
|
continue;
|
||||||
glActiveTexture(GL_TEXTURE2);
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h);
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h);
|
||||||
|
}
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index].m_blend_mode);
|
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index].m_blend_mode);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
@@ -2158,8 +2178,15 @@ Image Canvas::thumbnail_generate(int w, int h)
|
|||||||
m_layers[layer_index].m_rtt[i].unbindTexture();
|
m_layers[layer_index].m_rtt[i].unbindTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy the framebuffer before clearing to white
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
glActiveTexture(GL_TEXTURE2);
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
blendtex.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
blendtex.bind();
|
||||||
|
// copy the content of the fb before drawing the grid
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h);
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h);
|
||||||
|
|
||||||
// draw the grid
|
// draw the grid
|
||||||
@@ -2173,9 +2200,8 @@ Image Canvas::thumbnail_generate(int w, int h)
|
|||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
m_sampler_mask.bind(0); // linear
|
m_sampler_mask.bind(0); // linear
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
blendtex.bind();
|
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
|
|
||||||
blendtex.unbind();
|
blendtex.unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -267,9 +267,8 @@ void NodeCanvas::draw()
|
|||||||
ShaderManager::use(kShader::TextureBlend);
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
||||||
#ifndef __IOS__
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
#endif
|
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index].m_blend_mode);
|
ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index].m_blend_mode);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1, 1, -1, 1));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1, 1, -1, 1));
|
||||||
@@ -278,19 +277,21 @@ void NodeCanvas::draw()
|
|||||||
m_blender_rtt.bindTexture();
|
m_blender_rtt.bindTexture();
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
m_blender_rtt.bindTexture();
|
m_blender_rtt.bindTexture();
|
||||||
#ifndef __IOS__
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
glActiveTexture(GL_TEXTURE2);
|
{
|
||||||
m_blender_bg.bind();
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
|
m_blender_bg.bind();
|
||||||
m_blender_bg.size().x, m_blender_bg.size().y);
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
|
||||||
#endif
|
m_blender_bg.size().x, m_blender_bg.size().y);
|
||||||
|
}
|
||||||
|
|
||||||
m_face_plane.draw_fill();
|
m_face_plane.draw_fill();
|
||||||
|
|
||||||
#ifndef __IOS__
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
glActiveTexture(GL_TEXTURE2);
|
{
|
||||||
m_blender_bg.unbind();
|
glActiveTexture(GL_TEXTURE2);
|
||||||
#endif
|
m_blender_bg.unbind();
|
||||||
|
}
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
m_blender_rtt.unbindTexture();
|
m_blender_rtt.unbindTexture();
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
std::map<kShader, Shader> ShaderManager::m_shaders;
|
std::map<kShader, Shader> ShaderManager::m_shaders;
|
||||||
Shader* ShaderManager::m_current;
|
Shader* ShaderManager::m_current;
|
||||||
|
bool ShaderManager::ext_framebuffer_fetch = false;
|
||||||
|
|
||||||
bool Shader::create(const char* vertex, const char* fragment)
|
bool Shader::create(const char* vertex, const char* fragment)
|
||||||
{
|
{
|
||||||
@@ -157,6 +158,7 @@ GLint Shader::GetAttribLocation(const char* name)
|
|||||||
{
|
{
|
||||||
return glGetAttribLocation(prog, name);
|
return glGetAttribLocation(prog, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShaderManager::create(kShader id, const char* vertex, const char* fragment)
|
bool ShaderManager::create(kShader id, const char* vertex, const char* fragment)
|
||||||
{
|
{
|
||||||
m_shaders[id].name = id;
|
m_shaders[id].name = id;
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ class ShaderManager
|
|||||||
static std::map<kShader, Shader> m_shaders;
|
static std::map<kShader, Shader> m_shaders;
|
||||||
static Shader* m_current;
|
static Shader* m_current;
|
||||||
public:
|
public:
|
||||||
|
static bool ext_framebuffer_fetch;
|
||||||
static bool create(kShader id, const char* vertex, const char* fragment);
|
static bool create(kShader id, const char* vertex, const char* fragment);
|
||||||
static void use(kShader id);
|
static void use(kShader id);
|
||||||
static void use(const char* name);
|
static void use(const char* name);
|
||||||
|
|||||||
Reference in New Issue
Block a user